我在Rails应用程序上使用设计,出于各种原因,我需要使用此处的解决方案3添加自定义密码更改:https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-password
我已经查看了其他各种问题并试图通过多种方式扩充我的路线,但是网址总是出现/ users / update_password(没有传递参数),或者/users/update_password.254(带有参数传递)。我需要它是/ users / 254 / update_password。
以下是我正在使用的用户控制器(相关方法是update_password和user_params)。
class UsersController < ApplicationController
inherit_resources
load_and_authorize_resource
before_filter :authenticate_user!
def destroy
name = @user.to_s
destroy!(notice: "User #{@user.to_s} was deleted.")
end
def edit
@user = current_user
end
def update_password
@user = User.find(current_user.id)
if @user.update_with_password(user_params)
sign_in @user, :bypass => true
redirect_to root_path
else
render "edit"
end
end
private
def build_resource_params
[params.fetch(:user, {}).permit(:name, :email, :phone_number, :password, :password_confirmation).tap do |p|
p[:institution_pid] = build_institution_pid if params[:user][:institution_pid]
p[:role_ids] = build_role_ids if params[:user][:role_ids]
end]
end
def build_institution_pid
institution = Institution.find(params[:user][:institution_pid])
authorize!(:add_user, institution)
institution.id
end
def build_role_ids
[].tap do |role_ids|
roles = Role.find(params[:user][:role_ids].reject &:blank?)
roles.each do |role|
authorize!(:add_user, role)
role_ids << role.id
end
end
end
def user_params
params.required(:user).permit(:password, :password_confirmation, :current_password)
end
end
这是routes.rb的相关部分
devise_for :users
resources :users do
collection do
get 'password'
put 'update_password'
end
end
这是我创建的视图:
<div class="page-header">
<h1>Change Password</h1>
</div>
<%= 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="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %>
</div>
<div class="action_container">
<%= f.submit %>
</div>
这就是链接:(目前有一个参数,但我已经尝试过没有了)
<li><%= link_to "Change Password", update_password_users_path(current_user) %></li>
当我点击该链接时,我会被路由到在UsersController#show中显示ActiveRecord :: RecordNotFound的页面,找不到ID = update_password的用户。
我试图非常仔细地按照说明进行操作,并且我曾尝试过几次使用这些路线以使其正常工作,此时此刻我已经迷失了。有没有人见过这个,可以帮忙吗?谢谢!
答案 0 :(得分:1)
为了达到您的需要,您将拥有以下路线:
resources :users do
patch 'update_password', on: :collection
get 'edit_password', on: :member
end
然后,您将添加一个链接,引导用户update password form
。链接应如下所示:
<li><%= link_to "Change Password", edit_password_user_path(current_user) %></li>
该链接将导致users/edit_password.html.erb
:
<div class="page-header">
<h1>Change Password</h1>
</div>
<%= 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="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %>
</div>
<div class="action_container">
<%= f.submit %>
</div>
<% end %>
提交表单时,会在update_password
中触发UsersController
。这是控制器的代码:
class UsersController < ApplicationController
def edit_password
@user = current_user
end
def update_password
@user = User.find(current_user.id)
if @user.update_with_password(user_params)
sign_in @user, :bypass => true
redirect_to root_url
else
render "edit_password"
end
end
private
def user_params
params.required(:user).permit(:password, :password_confirmation, :current_password)
end
end