1

我有以下表格和控制器。

<%= 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 中的“密码/更改”相关联

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

4

3 回答 3

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)

我强烈建议你把它分开。

于 2012-06-17T04:45:32.287 回答
1

问题是您需要两种不同的方法。一个用于显示视图,一个用于处理表单发布。

现在你的密码控制器中的“更改”方法正在处理表单发布,所以你需要一个像“索引”这样的方法来显示表单

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
…

更新

而不是使用 verify 方法(在 rails 3 中删除),您应该将您的路由设置为 restful(Rails Routing from the Outside In),或者您可以创建一个特定的路由来更改密码,如下所示:

match 'password/change' => 'password#change', :via => :post
于 2012-06-17T04:49:49.343 回答
0

当您从浏览器呈现密码/更改时,params 为 nil,因此@np == @cp始终评估为 TRUE,执行更新、保存并执行重定向 - 事实上,如果您检查我会打赌用户的密码被设置为 nil。

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

这是否有助于为您指明正确的方向?

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

于 2012-06-17T04:45:12.357 回答