Cookies.delete doesn't work...?

Hello -

I’m trying to have an account information and link bar at the top of the
screen, i.e:

[email protected] | My Profile | Logout

This bar should be up there even when the user is on a cached page (the
app I’m working on has a lot of database-intensive screens, which
luckily are well-suited to page caching). So, I set up a before filter
in the application controller, like so:

before_filter :set_user_info_cookie
private
def set_user_info_cookie
cookies[:user_info] = { :value => current_user.email, :expires =>
1.hour.from_now } if current_user
cookies.delete :user_info unless current_user
end

(I’m using Authlogic for authentication)

Then I use jQuery to look for the “user_info” cookie - if it exists, it
assumes the user is logged in and puts the email address and whatnot at
the top of the screen. This is the only thing the cookie is used for, so
security’s not an issue (I don’t think) and it’s left in clear text.

There are two problems with my setup:

#1: “cookies.delete :user_info unless current_user” doesn’t work. In
fact, I can’t figure out how to destroy that cookie at all. When I use
the debugger, and then call cookies.delete [:user_info], I get the
following array with two strings:

[“user_credentials=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT”,
“user_info=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT”]

If I look at the cookies hash after that, it looks exactly the same as
it did before I tried to delete the user_info cookie. Looking at the
localhost cookies in Firefox, the user_info cookie is still there.

#2: I’ve just set up one controller specifically to serve static pages
(which will also be page cached, but I want to use rails to make sure
their layout matches the rest of the site). The controller actions are
empty, and the views are still very simple, but whenever I try to access
one of the static pages I get the following error, stemming from my
set_user_info_cookie method:


You have a nil object when you didn’t expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]

C:/Ruby/lib/ruby/gems/1.8/gems/authlogic-2.0.14/lib/authlogic/session/cookies.rb:101:in
cookie_credentials' C:/Ruby/lib/ruby/gems/1.8/gems/authlogic-2.0.14/lib/authlogic/session/cookies.rb:106:in persist_by_cookie’
C:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:178:in
send' C:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:178:in evaluate_method’
C:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:166:in
call' C:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:93:in run’
C:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:92:in
each' C:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:92:in send’
C:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:92:in
run' C:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:276:in run_callbacks’
C:/Ruby/lib/ruby/gems/1.8/gems/authlogic-2.0.14/lib/authlogic/session/callbacks.rb:78:in
persist' C:/Ruby/lib/ruby/gems/1.8/gems/authlogic-2.0.14/lib/authlogic/session/persistence.rb:55:in persisting?’
C:/Ruby/lib/ruby/gems/1.8/gems/authlogic-2.0.14/lib/authlogic/session/persistence.rb:39:in
find' C:/Ruby/Projects/myapp/app/controllers/application_controller.rb:22:in current_user_session’
C:/Ruby/Projects/myapp/app/controllers/application_controller.rb:27:in
current_user' C:/Ruby/Projects/myapp/app/controllers/application_controller.rb:14:in set_user_info_cookie’


Looking at cookies.rb at github:

Things are failing on the line:

controller.cookies[cookie_key] &&
controller.cookies[cookie_key].split(“::”)

So it seems that controller.cookies is nil. I feel like this must be
related to my other problem, but I don’t know how.

Does anyone have any ideas or suggestions? Sorry this was so long, but I
suppose, better too much information than too little.

Thanks so much!

Chris

2009/6/24 Chris H. [email protected]:

luckily are well-suited to page caching). So, I set up a before filter
(I’m using Authlogic for authentication)
the debugger, and then call cookies.delete [:user_info], I get the
following array with two strings:

[“user_credentials=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT”,
“user_info=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT”]

If I look at the cookies hash after that, it looks exactly the same as
it did before I tried to delete the user_info cookie. Looking at the
localhost cookies in Firefox, the user_info cookie is still there.

My experience has been that cookies.delete empties rather than
completely removes the cookie. So whenever I access a cookie that may
have been deleted I check for existence and not empty.

You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]

Things are failing on the line:

controller.cookies[cookie_key] &&
controller.cookies[cookie_key].split(“::”)

So it seems that controller.cookies is nil. I feel like this must be
related to my other problem, but I don’t know how.

I use just cookies[:cookie_name] to access the cookies (after checking
not nil and not empty)

Colin

My experience has been that cookies.delete empties rather than
completely removes the cookie. So whenever I access a cookie that may
have been deleted I check for existence and not empty.

Alright, but the cookie isn’t even being emptied. I can still see the
value in the cookies hash, and it still shows up in Firefox.

Is there a command to completely remove the cookie? I haven’t found one
yet.

Thanks!

2009/6/24 Chris H. [email protected]:

From previous post:

[“user_credentials=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT”,
“user_info=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT”]

user_info looks pretty empty to me.

Colin

But, like I was saying, it’s actually not empty. That’s my problem.

If I use “debugger” in that application controller action and start
inserting my own code:

cookies
=>
{“user_credentials”=>“5290…”, “user_info”=>“[email protected]”,
“_myapp_session”=>“rge…”}

cookies.delete :user_info
=>
[“user_info=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT”]

cookies
=>
{“user_credentials”=>“5290…”, “user_info”=>“[email protected]”,
“_myapp_session”=>“rge…”}

cookies[:user_info]
=>
[email protected]

It’s still there. And when I look at the cookies list in Firefox, it’s
there too.

2009/6/24 Colin L. [email protected]:

“_myapp_session”=>“rge…”}
cookies[:user_info]
=>
[email protected]

It’s still there. And when I look at the cookies list in Firefox, it’s
there too.

Having deleted the cookie in the controller and shown a view, what is
the value of that cookie when you get back to the controller again?

Further to this, if I remember correctly the cookies hash (or whatever
it is) is actually two separate sets of data, the incoming cookies
from the browser, accessed by value = cookies[:name], and the outgoing
values that will be sent to the browser, set by cookies[:name] =
value. This means that, non-intuitively, setting a cookie value (or
deleting it) and immediately reading it back does not show the new
value. It is not till it is sent to the browser and returned that the
new value will be seen. OTOH after a delete the cookie should be gone
or at least empty when examined in the browser. Are you sure you were
not confused by the write/read issue (as I was) and maybe you are
mistaken in saying that it still had a value when examined in the
browser.

Colin

http://www.railsforum.com/viewtopic.php?pid=1182#p1182

I did some googling, and this explains why the status doesn’t change
immediately - whatever changes are made to the cookie are sent with the
response headers, and the browser does the actual changing. That makes
sense.

2009/6/24 Chris H. [email protected]:

=>
[email protected]

It’s still there. And when I look at the cookies list in Firefox, it’s
there too.

Having deleted the cookie in the controller and shown a view, what is
the value of that cookie when you get back to the controller again?

Colin

Thanks for the explanation - sorry, I had that reply sitting open and I
forgot about it.

After I call delete on a cookie, jQuery can’t seem to find it, so I
suppose that it’s actually gone. But it still appears in Firefox’s
cookie list for some reason, and just waits to expire. I don’t know why.

2009/6/24 Chris H. [email protected]:

Thanks for the explanation - sorry, I had that reply sitting open and I
forgot about it.

After I call delete on a cookie, jQuery can’t seem to find it, so I
suppose that it’s actually gone. But it still appears in Firefox’s
cookie list for some reason, and just waits to expire. I don’t know why.

Posted via http://www.ruby-forum.com/.

I have just checked some similar code in my app. I call
cookies.delete :name in the controller and then redirect_to an action.
When I look at the cookies in FF (Edit, Settings, Privacy, Show
Cookies) then it is gone (rails 2.3.2), though I have definitely seen
the situation in the past when deleting a cookie it was just emptied.
This may have been on an earlier rails.

Colin

Chris H. wrote:

Hello -

I’m trying to have an account information and link bar at the top of the
screen, i.e:

[email protected] | My Profile | Logout

This bar should be up there even when the user is on a cached page (the
app I’m working on has a lot of database-intensive screens, which
luckily are well-suited to page caching).

So the majority of your page can be cached (the data part), while the
very top can change per user?

Fragment caching may simplify your issues. For my data-intensive app, I
use a dynamic menu (per user) at the top, while the remainder is built
from fragments.
Consider (this will likely render miserably, but bear with me):

11111111111111111111
222222222222222 3333
222222222222222 4444
222222222222222 5555
222222222222222 6666
222222222222222 7777

where 1 is the dynamic top menu, 2 is the cached fragment (show) for the
“current” model, and 3, 4, 5, 6, 7,… are cached fragments by type of
models related to the “current” model (fragments 3 thru 7 are also
cached as a meta-group of ‘relateds’).

On a ‘show’ page, 1 is generated, 2 is a cache read, and 3-7 is a single
cache read. Relate a new model of type 4, and fragment 4 is expired,
and the ‘relateds’ fragment is in expired. The next show for that same
model just requires reconstructing the fragment for type 4, and the
meta-fragment ‘realteds’.