在继续之前,让Rails等待表单提交

时间:2012-06-17 04:32:25

标签: ruby-on-rails forms redirect controller passwords

我有以下表格和控制器。

<%= 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

中的'密码/更改'有关

问题是,当我转到/密码/更改时,我立即重定向到家并收到“密码成功更改”的闪存通知。我从中获取的是,它不需要我单击提交按钮以传递参数。如何在继续通过控制器之前等待提交表单?

3 个答案:

答案 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。

在尝试更新之前,您需要确保参数不是空的。

这有助于指明正确的方向吗?

旁注:从代码可读性的角度来看,我可能会建议只使用内联变量而不是实例变量,但这只是我的观点:)