我有以下表格和控制器。
<%= form_tag do %>
<div>
<%= label_tag :Old %>
<%= password_field_tag :old_password %>
</div>
<div>
<%= label_tag :New %>
<%= password_field_tag :new_password %>
</div>
<div>
<%= label_tag :Confirm %>
<%= password_field_tag :confirm_password %>
</div>
<div>
<%= submit_tag "Update" %>
</div>
<% end %>
和控制器:
def change
@user = current_user
@op = params[:old_password]
@np = params[:new_password]
@cp = params[:confirm_password]
if @np == @cp
@user.update_with_password(:password => @np, :current_password=>@op)
if @user.save
flash[:notice] = "Password Successfully Changed"
redirect_to home_path
end
else
@user.errors.add("Incorrect confirmation")
end
end
这与config / routes.rb
中的'密码/更改'有关问题是,当我转到/密码/更改时,我立即重定向到家并收到“密码成功更改”的闪存通知。我从中获取的是,它不需要我单击提交按钮以传递参数。如何在继续通过控制器之前等待提交表单?
答案 0 :(得分:1)
最佳做法是将这两件事分成不同的控制器方法。一个应该用于简单地显示视图,而另一个应该用于处理POST请求。但是,如果你已经开始这么做了,我相信像这样的解决方案会起作用:
def change
@user = current_user
@op = params[:old_password]
@np = params[:new_password]
@cp = params[:confirm_password]
if @np && @np == @cp # This checks to see if params[:new_password] is nil
@user.update_with_password(:password => @np, :current_password=>@op)
我强烈建议你把它分开。
答案 1 :(得分:1)
问题在于您需要两种不同的方法。一个用于显示视图,另一个用于处理表单帖子。
现在你的password_controller中的“change”方法正在处理表单帖子,所以你需要一个像“index”这样的方法来显示表单
def index
#move your form to /views/password/index.html.erb or specifically render your 'change' view
end
然后在您的标记中将操作添加到表单
<%= form_tag('/password/change') do %>
…
然后在您的控制器中,您只能为更改方法指定POST
class PasswordController < ApplicationController
verify :method => :post, :only => :change
…
<强>更新强>
您应该将路由设置为restful(Rails Routing from the Outside In),或者您可以创建一个特定的路由来更改密码,而不是使用验证方法(在rails 3中删除):
match 'password/change' => 'password#change', :via => :post
答案 2 :(得分:0)
当您从浏览器呈现密码/更改时, params为nil ,因此@np == @cp
始终评估为TRUE,执行更新,保存并执行重定向 - 事实上,如果你检查我会打赌用户的密码被设置为nil。
在尝试更新之前,您需要确保参数不是空的。
这有助于指明正确的方向吗?
旁注:从代码可读性的角度来看,我可能会建议只使用内联变量而不是实例变量,但这只是我的观点:)