RoR 3:设计,拆分编辑用户表单以单独更改密码,devise_error_message没有方法错误!

发布于 2024-11-07 22:04:50 字数 310 浏览 0 评论 0原文

我试图将更改密码字段提取到单独的表单中,但使用方法 devise_error_message! 出现错误。

如果我删除更新工作正常的方法,但是,如果验证失败,它会重定向到 Registrations/edit.html.erb 并给出错误消息。我如何让它重定向回registrations/change_password.html.erb视图并给出devise_error_messages! ?

我所有的代码: http://pastie.org/1907545

I'm trying to pull the change password fields into a separate form, but get an error with method devise_error_message!.

If I remove the method updating workings fine, however, if a validation fails it redirects to the registrations/edit.html.erb and gives the error messages. How would I get it to redirect back to the registrations/change_password.html.erb view and give the devise_error_messages! ?

All my code :
http://pastie.org/1907545

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

偏闹i 2024-11-14 22:04:50

我认为有几件事需要解决。

1) 在change_password操作中初始化资源

devise_error_messages!的调用失败,因为您没有初始化资源(您的用户模型实例)在 RegistrationsController#change_password 操作中。实现此目的的一种方法是确保在 change_password 操作中调用在 Devise::RegistrationsController 中实现的 authenticate_scope! before 过滤器。在您的 RegistrationsController 中尝试类似的操作。

class RegistrationsController < Devise::RegistrationsController
    prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy, :change_password]

    def create
      ...
    end
end

如果这不起作用,您可能只需在 change_password 操作开始时调用 authenticate_scope! 即可。

2) 发生故障时重定向到change_password.html.erb

基本上是 Devise::RegistrationsController#edit 操作和您的 RegistrationsController#change_password 操作将表单提交给 Devise::RegistrationsController#update 操作。您想要做的是确保当更新失败时,如果表单提交来自 Devise::RegistrationsController#edit 操作,那么您将呈现 registrations/edit.html.erb 视图,类似地,如果表单提交来自 RegistrationsController#change_password 操作,则您将呈现 registrations/change_password.html.erb 视图。

有多种方法可以执行此操作,包括依靠 flash 哈希在 RegistrationsController#change_password 操作中设置密钥(例如 flash[:change_password] = true),然后检查如果更新期间发生错误,则确定此密钥是否存在。另一种方法是在 Change_password 表单中使用隐藏字段,然后类似地,如果更新期间发生错误,请检查 params 哈希中是否存在此隐藏字段。像这样的东西。

<h2>Edit <%= resource_name.to_s.humanize %></h2>

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name),
                       :html => { :method => :put }) do |f| %>  

  <%= devise_error_messages! %>

  <%= hidden_field_tag :change_password, true %>

无论哪种方式,您都需要重写 Devise::RegistrationsController#udpate 操作。像这样的事情:

class RegistrationsController < Devise::RegistrationsController
    prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy, :change_password]

    def update
      if resource.update_with_password(params[resource_name])
        set_flash_message :notice, :updated if is_navigational_format?
        sign_in resource_name, resource, :bypass => true
        respond_with resource, :location => after_update_path_for(resource)
      else
        clean_up_passwords(resource)
        respond_with_navigational(resource) do
          if params[:change_password] # or flash[:change_password]
            render_with_scope :change_password
          else
            render_with_scope :edit
          end
        end
      end
    end
end

尝试一下,但我认为这应该会让你回到正轨。

There's a few things that I think need to be resolved.

1) Initialize the resource in the change_password action

The call to devise_error_messages! fails because you aren't initializing the resource (your User model instance) in the RegistrationsController#change_password action. One way to do this is to make sure that the authenticate_scope! before filter, which is implemented in Devise::RegistrationsController, gets called on the change_password action. Try something like this in your RegistrationsController.

class RegistrationsController < Devise::RegistrationsController
    prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy, :change_password]

    def create
      ...
    end
end

If that doesn't work, you might want to simply call authenticate_scope! at the beginning of your change_password action.

2) Redirect to change_password.html.erb in case of a failure

Basically both of the Devise::RegistrationsController#edit action and your RegistrationsController#change_password action submit a form to the Devise::RegistrationsController#update action. What you want to do is make sure that when an update fails, if the form submission is coming from the Devise::RegistrationsController#edit action then you render the registrations/edit.html.erb view and similarly if the form submission is coming from the RegistrationsController#change_password action then you render registrations/change_password.html.erb view.

There are various ways to do this including relying on the flash hash to set a key in the RegistrationsController#change_password action (e.g. flash[:change_password] = true) and then check for the presence of this key if an error occurs during an update. Another approach would be to use a hidden field in your change_password form then similarly, if an error occurs during an update, check for the presence of this hidden field in the params hash. Something like this.

<h2>Edit <%= resource_name.to_s.humanize %></h2>

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name),
                       :html => { :method => :put }) do |f| %>  

  <%= devise_error_messages! %>

  <%= hidden_field_tag :change_password, true %>

Either way you will need to override the Devise::RegistrationsController#udpate action. Something like this:

class RegistrationsController < Devise::RegistrationsController
    prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy, :change_password]

    def update
      if resource.update_with_password(params[resource_name])
        set_flash_message :notice, :updated if is_navigational_format?
        sign_in resource_name, resource, :bypass => true
        respond_with resource, :location => after_update_path_for(resource)
      else
        clean_up_passwords(resource)
        respond_with_navigational(resource) do
          if params[:change_password] # or flash[:change_password]
            render_with_scope :change_password
          else
            render_with_scope :edit
          end
        end
      end
    end
end

Give this a try but I think that should put you back on track.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文