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.
精彩评论