Reputation: 410
In the tutorial (4th edition, for Rails 5) I've come to chapter 12.
If the password is forgotten, the password can be reset. I checked and double-checked my code, also compared it to the files in Bitbucket by Michael:
https://bitbucket.org/railstutorial/sample_app_4th_ed/src/6c255b27f7c7935dd9b04f28d3a249af8618242f/?at=password-reset
What happens? After the password reset email is send (no problems there, afaik), the text says" following the link from Listing 12.11 should render a password reset form. The result appears in Figure 12.11."
However, the reset form does not show up; instead I am immediately redirected to the root, with no message or error.
I found a similar question asked before, but could not figure out what the solution was; where to look for mistakes?
I still can be considered to be a newby, unfortunately, I have no real clue how to solve this....
Thank you for any help, Ad
The answer is helpful, however, does not yet help me enough; I will edit with more information: (in $ rails console
) I entered:
>> User.find_by(email: "[email protected]")
User Load (1.4ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "[email protected]"], ["LIMIT", 1]]
=> #<User id: 1, name: "Example User", email: "[email protected]", created_at: "2016-07-28 22:52:07", updated_at: "2016-08-03 16:51:52", password_digest: "$2a$10$IFxi0SPvA/I4rY53g.PrF.Ihxgb9.KtZpC2jcjWLgqk...", remember_digest: nil, admin: true, activation_digest: "$2a$10$J49AUluY8tSVExQBeDeCoO3U8bCHgNEgNjMyVtFmzT6...", activated: true, activated_at: "2016-07-28 22:52:06", reset_digest: "$2a$10$GGExFYbJIqhqSZq.Nc7hUeJhnbTRmtPjsAd89K99X8L...", reset_sent_at: "2016-08-03 16:51:52">
You see that this "Example User" is activated, and that a reset is sent. The 'problem' (or challenge) thus lies in the authenticated?(attribute, token) method; isn't that obvious?
How can I look into the 'inner workings' of this method? For me as a newbie, I am breaking my head how this could be done.
pry
is new for me; Hartl's tutorial does not mention this, till now. The only possible option I have seen, is debugger
. Could that be used?
Another question, about :reset
What exactly is this? A symbol? But what is the symbol representing? Does it refer to a method, a variable, inbuilt?
I was thinking, maybe more debug information could be put on the screen? For instance, in app/views/layouts/application.html.erb
if have this line:
<%= debug(params) if Rails.env.development? %>
Could that be enhanced?
Update: I found out that the screen from figure 12.11 does show up, when I comment out the last line: redirect_to root_url
Upvotes: 4
Views: 323
Reputation: 91
The thing is that -- @user.authenticated?(:reset, params[:id]) -- is evaluated as false, because of a typo that I had in my code in user.rb create_reset_digest method. The part where you update the attribute User.digest(:reset_token) --> was, should be --> User.digest(reset_token) --, without " : ", so for anyone that stumbles on this look for typo in the code, because the code works...
Upvotes: 0
Reputation: 31
I got this same scenario too as I follow the hartl's tutorial(rails 5 version). In my case, I found out that I was being redirected to the root_url because the email I was using was for a user that wasn't activated yet (making @user.activated? == false
)
I guess, this kind of unexpected behavior happens because sometimes we test using data from a database that we seed ourselves in development mode, that we do not notice that we have left out some processes an account goes through in production mode.
the first answer was informative to me, which prompt me to use the rails console to type each condition and know its value. again in my case, @user
was true, but @user.activated?
was false.
What I did next was restructure the valid_user
method with flash messages:
def valid_user
if @user
if @user.activated?
unless @user.authenticated?(:reset, params[:id])
flash[:danger] = "Reset token do not match."
redirect_to root_url
end
else
flash[:danger] = "User is not yet activated."
redirect_to root_url
end
else
flash[:danger] = "User does not exist."
redirect_to root_url
end
end
Now I know what invalidates the user. And so that, in the future, if ever every else cases will still happen in production mode, I have an idea where the issues starts.
In my case, I was unknowingly at first trying to reset the password of a user account that didn't go through activation yet. I would want to make the system not send an email if the account is not activated yet, and I might like to send an email for a notice for an activation first to inform the user to activate their account first before even changing their password.
But that's for another production cycle, which the Rails tutorial had left out because this is the initial cycle of password reset functionality and some other secondary scenarios is for you, the developer, to decide.
Upvotes: 1
Reputation: 36860
In the app/controllers/passwords_resets_controller.rb notice that there's a few before_action
calls for the edit action. One of them is...
before_action :valid_user, only: [:edit, :update]
def valid_user
unless (@user && @user.activated? &&
@user.authenticated?(:reset, params[:id]))
redirect_to root_url
end
end
the redirect_to root_url
is exactly the problem you're encountering, so it must be that (a) there's no @user
found, or (b) @user.activated?
is not true or (c) @user.authenticated?(:reset, params[:id])
is not true.
So to solve this, you'll need to find out which of those conditions are failing and then find out why. You can do this with pry
(I don't know if the Hartl tutorial covers pry
) or you may want to set up some Rails.logger.info lines to inspect the variables.
Upvotes: 1