My method is executing, but Devise is not using the return value at all. On the sign in page, it just reloads the page with a 'Signed in successfully' notice. It doesn't redirect to the value returned from the method.
Log
Started POST "/users/sign_in" for 127.0.0.1 at 2018-03-05 22:19:50 -0500 Processing by Users::SessionsController#create as HTML Parameters: {"utf8"=>"√", "authenticity_token"=>"tQd5a43StP85oyyCpEmFU8cAkFXdJL2OLpuAK1+sqQC6/rIqcd+fB2iE4RT0RoPKPCqreNBYlv2bxjl9gZFrWg==", "user"=>{"email"=>"test11@example.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"} User Load (2.0ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["email", "test11@example.com"], ["LIMIT", 1]] (5.0ms) BEGIN User Exists (3.0ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 AND ("users"."id" != $2) LIMIT $3 [["email", "test11@example.com"], ["id", 23], ["LIMIT", 1]] Sector Load (0.0ms) SELECT "sectors".* FROM "sectors" INNER JOIN "sectors_users" ON "sectors"."id" = "sectors_users"."sector_id" WHERE "sectors_users"."user_id" = $1 [["user_id", 23]] Region Load (0.0ms) SELECT "regions".* FROM "regions" INNER JOIN "regions_users" ON "regions"."id" = "regions_users"."region_id" WHERE "regions_users"."user_id" = $1 [["user_id", 23]] Criterium Load (0.0ms) SELECT "criteria".* FROM "criteria" INNER JOIN "criteria_users" ON "criteria"."id" = "criteria_users"."criterium_id" WHERE "criteria_users"."user_id" = $1 [["user_id", 23]] AssetType Load (0.0ms) SELECT "asset_types".* FROM "asset_types" INNER JOIN "asset_types_users" ON "asset_types"."id" = "asset_types_users"."asset_type_id" WHERE "asset_types_users"."user_id" = $1 [["user_id", 23]] Company Load (1.0ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2 [["id", 42], ["LIMIT", 1]] (5.0ms) ROLLBACK ############### /users/23/edit Rendering users/sessions/new.haml within layouts/application Rendered users/shared/_links.html.erb (3.0ms) Rendered users/sessions/new.haml within layouts/application (251.2ms) Rendered layouts/_footer.haml (15.0ms) Completed 200 OK in 6554ms (Views: 3364.9ms | ActiveRecord: 86.1ms)
Notice it is rendering users/sessions/new.haml
instead of the edit page?
Code
class ApplicationController < ActionController::Base ... def after_sign_in_path_for(resource) logger.debug '############### ' + edit_user_path(resource) if resource.is_a?(User) && resource.signature.blank? return edit_user_path resource if resource.is_a?(User) && resource.signature.blank? stored_location_for(resource) || if resource.is_a?(User) dashboard_path elsif resource.is_a?(Facilitator) && resource.name.nil? edit_facilitator_path resource elsif resource.is_a?(Facilitator) facilitator_path resource else super end end
I completely commented out the method and it still reloaded the login page.
Started POST "/users/sign_in" for 127.0.0.1 at 2018-03-05 22:25:21 -0500 ... Rendering users/sessions/new.haml within layouts/application
Devise 4.4.0
Documentation:
I added
def after_sign_in_path_for(resource) logger.debug '############# ' + resource.errors.full_messages.join(', ')
And did discover validation errors like
############# Title can't be blank, Country can't be blank, Signature can't be blank, ...
But it does show the notice
Signed in successfully.
And I do have a session and can navigate elsewhere. My validations are on: :update
.
validates :email, :name, :title, :phone, :address1, :city, :state, :zip, :country, :type, :signature, presence: true, on: :update
This should not cause log in behavior errors.
I commented all validations on the model and it does work, but this is highly unusual! Validations should not affect login behavior. There has to be a workaround.
Started POST "/users/sign_in" for 127.0.0.1 at 2018-03-05 23:11:43 -0500 SQL (15.0ms) UPDATE "users" SET "current_sign_in_at" = $1, "last_sign_in_at" = $2, "current_sign_in_ip" = $3, "sign_in_count" = $4, "updated_at" = $5 WHERE "users"."id" = $6 [["current_sign_in_at", "2018-03-06 04:11:44.225501"], ["last_sign_in_at", "2017-11-09 01:22:28.245231"], ["current_sign_in_ip", "127.0.0.1/32"], ["sign_in_count", 6], ["updated_at", "2018-03-06 04:11:44.230506"], ["id", 23]] Redirected to http://localhost:3000/users/23/edit Completed 302 Found in 2183ms (ActiveRecord: 48.0ms)
3 Answers
Answers 1
As you only want your validations on update, I guess that you only need them for a specific form, since your users are still valid even without this validations. In that case I would use a so called form object, that does the on update validations for you and remove the on update validations on your user model. In that case your validations don't affect other parts of your app.
Here is a good guide on how to do that with just using ActiveModel.
An alternative could be to add a virtual attribute to the model and run your validations conditionally in the user controller.
Answers 2
You might need conditional validation on your model. Something like this:
validates :email, :name, :title, :phone, :address1, :city, :state, :zip, :country, :type, :signature, presence: true, on: :update, unless: Proc.new {|user| user.sign_in_at.present? }
Devise will update sign_in_at
whenever sign_in happens. Which will trigger update action and related validations.
Also Documentation said the allow_nil: true
instruct the model to validate the fields ONLY if it exists on the submitted form.
Answers 3
Check this documentation https://github.com/plataformatec/devise/wiki/How-To:-redirect-to-a-specific-page-on-successful-sign-in. They have clearly mentioned when you will go in loop and solution for it. Check Preventing redirect loops section in above doc.
0 comments:
Post a Comment