Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ajax Delete links log out current_user

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 logged 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.

like image 215
Andrew Avatar asked Jun 22 '11 02:06

Andrew


2 Answers

I had a similar problem. Solution was as simple as adding

<%= csrf_meta_tag %>

to the layout.

like image 144
DiegoFrings Avatar answered Nov 11 '22 07:11

DiegoFrings


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.

like image 38
Andrew Avatar answered Nov 11 '22 07:11

Andrew