The title pretty much explains it. I'm having an odd situation where views that allow users to delete notifications using Ajax cause the current_user to be logg开发者_运维百科ed out. I don't even know where to begin debugging this...
Here's the controller
class NotificationsController < ApplicationController
def destroy
@notification = Notification.find(params[:id])
@notification.destroy
respond_to do |format|
format.js
end
end
end
This is the entire controller, nothing is abridged. The notifications are generated by the system, so the only action a user can take is to "dismiss" (ie. delete) them.
I also tried this using the newer respond_with
syntax and had the same effect.
I'm using Devise, and Rails 3.0.9. Any idea what could be going on -- or suggestions on how to debug??
-- EDIT 1 --
Routes.rb
resources :notifications, :only => [:destroy]
Delete link
%span.delete= link_to( 'dismiss', notification_path(notification), :method => :delete, :remote => true )
-- EDIT 2 --
Well, I noticed something new in the logs -- see **** below.
Started DELETE "/notifications/10" for 127.0.0.1 at 2011-06-21 21:47:15 -0500
Processing by NotificationsController#destroy as JS
Parameters: {"id"=>"10"}
SQL (0.4ms) SELECT name
FROM sqlite_master
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
SQL (0.3ms) SELECT name
FROM sqlite_master
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Slug Load (0.4ms) SELECT "slugs".* FROM "slugs" WHERE ("slugs".sluggable_id = 1 AND "slugs".sluggable_type = 'User') ORDER BY id DESC LIMIT 1
****AREL (0.3ms) UPDATE "users" SET "remember_token" = NULL, "remember_created_at" = NULL, "updated_at" = '2011-06-22 02:47:15.913839', "preferences" = '---
:email_notifications: ''true''
' WHERE "users"."id" = 1
Notification Load (0.2ms) SELECT "notifications".* FROM "notifications" WHERE "notifications"."id" = 10 LIMIT 1
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
AREL (0.3ms) UPDATE "users" SET "notifications_count" = COALESCE("notifications_count", 0) - 1 WHERE "users"."id" = 1
AREL (0.1ms) DELETE FROM "notifications" WHERE "notifications"."id" = 10
Rendered notifications/destroy.js.erb (0.7ms)
Completed 200 OK in 6416ms (Views: 9.6ms | ActiveRecord: 4.1ms)
So, there it is, it looks like part of the users table is getting set to null, particularly the remember_token which I suspect is triggering Devise to end the session, or maybe this is done by Devise after the session is destroyed. But how do I track that down?
The only thing I can think of that causes notifications to interact with Users is there's a counter_cache
on Users for notifications_count
.
I appreciate thoughts and suggestions on how to debug!
-- EDIT 3 --
After digging with ruby-debug it looks like the issue is related to Devise and changes to the rails.js script. See:
https://github.com/plataformatec/devise/issues/913
https://github.com/ryanb/cancan/issues/280
I'm trying out some of the suggestions on those threads and will post if I find a solution.
I had a similar problem. Solution was as simple as adding
<%= csrf_meta_tag %>
to the layout.
It turns out this had to do with changes to the Rails jQuery UJS driver and Devise. I had updated Devise without updating jQuery UJS -- and Devise was expecting the CSRF token to be handled differently, so it was processing the ajax request as unauthorized which meant destroying the current user's session. Upgrading to the latest jQuery Rails driver fixed the problem.
Are you sure this controller and action are the ones that are triggered by the request? It sounds like the path you are DELETEing isnt right and you are hitting your sessions path instead.
Is it possible that the destroy notification path is redirecting to the session destroy path through JS?
Do you have destroy.js template in your notifications views? try adding one that is empty see if you get a different result.
精彩评论