我在理解下面在网上找到的密码重置代码的app逻辑时遇到了问题。
在我感到困惑的地方。
我的问题是 - 如果@user = nil if @user.update_attributes(:password => params[:user][:password], :password_confirmation => params[:user][:password_confirmation])
# app/controllers/users_controller.rb
def reset
@user = User.find_by_reset_code(params[:reset_code]) unless params[:reset_code].nil?
if request.post?
if @user.update_attributes(:password => params[:user][:password], :password_confirmation => params[:user][:password_confirmation])
self.current_user = @user
@user.delete_reset_code
flash[:notice] = "Password reset successfully for #{@user.email}"
redirect_to root_url
else
render :action => :reset
end
end
end
<!-- app/views/users/reset.html.erb -->
<%= error_messages_for :user %>
<% form_for :user do |f| -%>
<p>
Pick a new password for <span><%= @user.email %></span>
</p>
<p>
<label for="password">Password</label><br />
<%= f.password_field :password %>
</p>
<p>
<label for="password">Confirm Password</label><br />
<%= f.password_field :password_confirmation %>
</p>
<p>
<%= submit_tag 'Reset' %>
</p>
<% end -%>
答案 0 :(得分:1)
如果@user = nil
,此代码如何有效
重置代码(不是您粘贴的视图)会查找具有相同reset_code的用户...如果找不到,则用户为零。如果重置代码存在,它将不是nil,而是true并返回记录。
答案 1 :(得分:1)
我认为你误解了逻辑的流动。您提供的视图用于请求密码重置电子邮件。电子邮件可能包含重置的网址,其中包含reset_code参数。检查reset.html视图以确保在那里处理reset_code参数。
答案 2 :(得分:1)
表单提交动作时 再次被召唤。
request.post?
if语句检查他们是否正在提交表单。其中的内容仅在表单提交POST
请求时执行,否则,它将呈现您看到的页面。
这次参数中没有重置代码,因此找不到用户@user = nil
页面未呈现,因此不将用户设置为任何内容都可以,它将重定向回主URL,该主URL将使用户基于会话或cookie,而不是重置代码。
这次是一个帖子请求,所以我们输入逻辑的那一部分。
虽然我无法弄清楚@user.update_attributes
是如何运作的,因为就像你说的那样,最后会有unless
陈述。
答案 3 :(得分:1)
我的回答是它是错误的代码。
首先,应通过表单上的隐藏字段或URL中的参数将reset_code传递回控制器。
其次,如果没有传入reset_code(如图所示),@ user将为nil,你将得到一个AV。您需要在代码周围添加一个保护条款:
if !@user
flash.now[:notice] = "User not found."
elsif request.post?
...
此外,如果代码中没有包含它,您需要一些使重置代码到期的方法。在我的系统上,它们会在五天后过期。您需要在users表中添加一个额外的字段。将代码发送的日期存储在那里,并包含另一个在给定时间范围内的保护条款。
(请记住,只是因为你在'网上找到它并不意味着它是正确的并且没有bug)。