Question

I'm building an Rails 4 app with the authentication gem 'clearance'. I'm kind of stuck with the following problem:

When an user forgets his/her password and would like to set a new password, the user is not found. (but exist in DB), this is the server log:

Started PUT "/passwords/1?token=[FILTERED]" for 127.0.0.1 at 2013-08-10 21:00:58 +0200
Processing by PasswordsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "password_reset"=>"[FILTERED]", "token"=>"[FILTERED]", "id"=>"1"}
  User Load (1.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" IS NULL AND "users"."confirmation_token" = 'bcc6a5b49bc64628eff15bf92761fe1775ef252c' LIMIT 1
  Rendered passwords/new.html.slim within layouts/application (0.9ms)
  Rendered partials/_favicon_styles.html.slim (0.4ms)
  User Load (0.9ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  Rendered partials/_navigation.html.slim (11.2ms)
  Rendered partials/_notification.html.slim (0.1ms)
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  Rendered partials/_footer.html.slim (1.0ms)
Filter chain halted as :forbid_non_existent_user rendered or redirected
Completed 200 OK in 38ms (Views: 33.0ms | ActiveRecord: 2.3ms)

But when a user is logged in, he or she can change password and also login works normally ..

I think the problem is in the query, I am sending the id with the form, but when the id reaches the query it says IS NULL. But I've struggled with it for hours, but can't find the solution.

Also is the 7 times request for cache a problem?

Thanks in advance!

Update

Changed the strong parameters and the 'find_user_by_id_and_confimatrion_token' method as followed:

  def find_user_by_id_and_confirmation_token
    Clearance.configuration.user_model.
    find_by_id_and_confirmation_token params[:**id**], params[:token].to_s  
  end

This was :user_id, this is not the name of the params.

  def password_reset_params
    # if params.has_key? :user
    #   ActiveSupport::Deprecation.warn %{Since locales functionality was added, accessing params[:user] is no longer supported.}
    #   params[:user][:password]
    # else
    #   params[:password_reset][:password]
    # end

    params.require(:password_reset).permit(:password_reset, :password, :token, :id)
  end

But this throws in another error:

Started PUT "/passwords/1?token=[FILTERED]" for 127.0.0.1 at 2013-08-11 16:31:20 +0200
  Processing by PasswordsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "password_reset"=>"       [FILTERED]", "token"=>"[FILTERED]", "id"=>"1"}
  User Load (1.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."confirmation_token" = 'd892a4698f5eff29e34378716ebd46414ad6e8cf' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."confirmation_token" = 'd892a4698f5eff29e34378716ebd46414ad6e8cf' LIMIT 1
  (0.4ms)  BEGIN
  User Exists (1.0ms)  SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'user@test.nl' AND "users"."id" != 1) LIMIT 1
  (0.4ms)  ROLLBACK
  Rendered passwords/edit.html.slim within layouts/application (1.2ms)
  Rendered partials/_favicon_styles.html.slim (0.3ms)
  User Load (0.9ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  Rendered partials/_navigation.html.slim (4.7ms)
  Rendered partials/_notification.html.slim (0.1ms)
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  Rendered partials/_footer.html.slim (0.4ms)
Completed 200 OK in 112ms (Views: 12.5ms | ActiveRecord: 4.1ms)

It says that the user already exists, and rollback the changes. Because this is an update, the user must exist.

Update 2

I'm still trying to fix this issue, here the difference between a logged in user who's editing their password, and via password forget method (not logged in)

Logged in user changing password

Started PATCH "/admin/users/1" for 127.0.0.1 at 2013-08-13 16:12:07 +0200
  Processing by Admin::UsersController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "user"=>{"password"=>"     [FILTERED]", "password_confirmation"=>"[FILTERED]"}, "id"=>"1"}
  User Load (1.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'f1078c2b74f6b3b3c9950b87a5b927db3f2bffcd' LIMIT 1
  User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1(0.4ms)    
  BEGIN
  User Exists (1.0ms)  SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'info@netventief.nl' AND "users"."id" != 1) LIMIT 1
  SQL (1.6ms)  UPDATE "users" SET "encrypted_password" = $1, "updated_at" = $2 WHERE "users"."id" = 1  [["encrypted_password", "$2a$10$F4p6N0va/TY2nKOiXOSQ7e23NnHPyDytQZ6EvhtGd7FJ2oTMVFbSS"], ["updated_at", Tue, 13 Aug 2013 16:12:07 CEST +02:00]](12.6ms)
  COMMIT
  Rendered admin/users/edit.html.slim within layouts/application (8.7ms)
  Rendered partials/_favicon_styles.html.slim (0.3ms)
  Rendered partials/_olderbrowser.html (0.0ms)
  Rendered partials/_navigation.html.slim (2.6ms)
  Rendered partials/_notification.html.slim (0.1ms)
  Rendered partials/_footer.html.slim (0.1ms)
Completed 200 OK in 167ms (Views: 23.0ms | ActiveRecord: 17.3ms)

User who is forgotten the password and would enter a new password

Started PUT "/passwords/1?token=[FILTERED]" for 127.0.0.1 at 2013-08-13 16:58:45 +0200
  Processing by PasswordsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "user"=>{"password"=>"[FILTERED]"}, "token"=>"[FILTERED]", "id"=>"1"}
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."confirmation_token" = 'b198361b098c1bf110a2171dd7f00258d9ca9240' LIMIT 1
  CACHE   
  (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."confirmation_token" = 'b198361b098c1bf110a2171dd7f00258d9ca9240' LIMIT 1
  (0.3ms)BEGIN
  User Exists (0.5ms)  SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'info@netventief.nl' AND "users"."id" != 1) LIMIT 1
  (0.2ms) ROLLBACK
  Rendered passwords/edit.html.slim within layouts/application (1.4ms)
  Rendered partials/_favicon_styles.html.slim (0.3ms)
  Rendered partials/_olderbrowser.html (0.0ms)
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  Rendered partials/_navigation.html.slim (5.0ms)
  Rendered partials/_notification.html.slim (0.1ms)
  CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
  Rendered partials/_footer.html.slim (0.5ms)
Completed 200 OK in 102ms (Views: 14.7ms | ActiveRecord: 2.0ms)

Still expect the Put/Patch method and all the cache alerts. This seems pretty the same to me .. I have tried to use the patch http method, but it didn't help.

Update 3

Also my controller code, its pretty much the same as Clearance::PasswordsController. Removed methods that are not called by my problem.

require 'active_support/deprecation'

class PasswordsController < ApplicationController

skip_before_filter :authorize, :only => [:create, :edit, :new, :update]
before_filter :forbid_missing_token, :only => [:edit, :update]
before_filter :forbid_non_existent_user, :only => [:edit, :update]

def edit
  @user = find_user_for_edit
  render :template => 'passwords/edit'
end

def update
  @user = find_user_for_update

  if @user.update_attributes( password: password_reset_params )
    sign_in @user
    redirect_to url_after_update
  else
    flash_failure_after_update
    render :template => 'passwords/edit'
  end
end

private

def password_reset_params
  if params.has_key? :user
    ActiveSupport::Deprecation.warn %{Since locales functionality was added, accessing params[:user] is no longer supported.}
    params[:user][:password]
  else
    params[:password_reset][:password]
  end
end

def find_user_by_id_and_confirmation_token
  Clearance.configuration.user_model.
    find_by_id_and_confirmation_token params[:id], params[:token].to_s
end

def find_user_for_edit
  find_user_by_id_and_confirmation_token
end

def find_user_for_update
  find_user_by_id_and_confirmation_token
end

def forbid_missing_token
  if params[:token].to_s.blank?
    flash_failure_when_forbidden
    render :template => 'passwords/new'
  end
end

def forbid_non_existent_user
  unless find_user_by_id_and_confirmation_token
    flash_failure_when_forbidden
    render :template => 'passwords/new'
  end
end
end
Was it helpful?

Solution

You should track down where the following SQL query is being triggered from:

User Exists (0.5ms)  SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'info@netventief.nl' AND "users"."id" != 1) LIMIT 1

This is the line that is causing your save to fail. My guess is that you have a validation or some other callback on your User model that is firing when you are calling @user.update_attributes. The validation/callback is failing, which is causing the save to fail.

OTHER TIPS

This is the line that is causing your save to fail. My guess is that you have a validation or some other callback on your User model that is firing when you are calling @user.update_attributes. The validation/callback is failing, which is causing the save to fail.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top