Reputation: 121
On a rails app setup with Devise, i am trying to provide users with a form to change passwords.
i have followed the solution 3 from the Devise wiki:https://github.com/heartcombo/devise/wiki/How-To:-Allow-users-to-edit-their-password
and accordingly have in a user controller
class UsersController < Devise::RegistrationsController
def update_password
@user = current_user
if @user.update(user_params)
# Sign in the user by passing validation in case their password changed
bypass_sign_in(@user)
redirect_to root_path
else
render "edit"
end
end
end
routes.rb
devise_for :users,
path: "", path_names: {
sign_in: "login",
sign_out: "logout",
sign_up: "register",
edit: "settings"
},
controllers: {
registrations: "users",
sessions: "users/sessions"
}
resources :users do
patch 'update_password'
end
Rake routes gives me :
user_update_password_path POST (/:locale)/users/:user_id/update_password(.:format)
users#update_password {:locale=>/fr|en|de/}
the link to access the menu is the following:
<%= link_to user_update_password_path(current_user) %>
in browser, that links directs me to :
but I receive a Routing error
No route matches [GET] "/en/users/1/update_password"
When I wrap the
resources :users do
resources :wishlists
collection do
patch 'update_password'
end
end
the link_to send to
Which results in the error
undefined local variable or method `user_update_password_path' for
<#:0x00007f86cfe48f10> Did you mean? user_password_path
however, rails routes shows:
update_password_users PATCH (/:locale)/users/update_password(.:format) users#update_password {:locale=>/fr|en|de/}
but a link_to
update_password_users_path
results in an error
Could not find devise mapping for path "/en/users/update_password". This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do get "/some/route" => "some_devise_controller" end
2) You are testing a Devise controller bypassing the router. If so, you can explicitly tell Devise which mapping to use:
@request.env["devise.mapping"] = Devise.mappings[:user]
What have I missed ?
Upvotes: 0
Views: 5392
Reputation: 1179
First of all in the solution 3 it says resource
not resources
. Watch the differences carefully between yours and the below one -
resource :user, only: [:edit] do
collection do
patch 'update_password'
end
end
Second the like should direct to edit_user_path
not update_password_user
as that is the patch
route.
Third, you have to add a edit
action to your controller as the wiki suggests. And also a form for the action.
before_action :authenticate_user!
def edit
@user = current_user
end
and in app/views/users/edit.html.erb
<%= form_for(@user, :url => { :action => "update_password" } ) do |f| %>
<div class="field">
<%= f.label :password, "Password" %><br />
<%= f.password_field :password, :autocomplete => "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="action_container">
<%= f.submit %>
</div>
<% end %>
You missed lots of things. Try reading the wiki again.
Upvotes: 0