开发者

RoR 3 : Devise, splitting edit user form to separate the change password, no method error for devise_error_message!

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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜