我关注cancancan身份验证this tutorial,特别希望管理员在不需要密码的情况下更新用户。我也看过this建议,但我不确定如何将其改编为我自己的代码。当我点击更新时,它会在UsersController#update'中显示“NoMethodError”。私有方法`update_without_password'要求nil:NilClass
我的应用会返回所有用户的参数,所以我不明白这里发生了什么。对于rails来说还是一个新手 - 如果您需要任何进一步的信息,请告诉我。提前谢谢!
USERS CONTROLLER
class UsersController < ApplicationController
before_filter :authenticate_user!
def update
if user_params[:password].blank?
user_params.delete(:password)
user_params.delete(:password_confirmation)
end
successfully_updated = if needs_password?(@user, user_params)
@user.update(user_params)
else
@user.update_without_password(user_params)
end
respond_to do |format|
if successfully_updated
format.html { redirect_to @user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
rescue ActiveRecord::RecordNotFound
respond_to_not_found(:js, :xml, :html)
end
private
def needs_password?(user, params)
params[:password].present?
end
def update_without_password(user_params)
user.update_without_password(user_params)
end
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :name, :role_id, :accepted)
end
编辑表格
<h3><%= @user == @current_user ? "Your Account Settings" : "Edit User" %></h3>
<%= form_for(@user, :html => { :method => :put }) do |f| %>
<p><%= f.label :first_name %></p>
<p><%= f.text_field :first_name %></p>
<p><%= f.label :last_name %></p>
<p><%= f.text_field :last_name %></p>
<p><%= f.label :email %></p>
<p><%= f.text_field :email %></p>
<% if can? :read, Role %>
<%= collection_select(:user, :role_id, Role.all, :id, :name, {prompt: true}) %>
<% end %>
<p><%= f.submit "Update" %></p>
<% end %>
我在这里缺少什么?请告诉我是否应该提供其他任何东西。谢谢!
答案 0 :(得分:3)
我认为您看到该错误是因为@user
未在update
方法中实例化。您需要将@user
设置为User
模型的实例。如果没有看到您的完整应用,我无法确定,但您应该可以访问params哈希中的:id
,从而可以设置@user
执行以下操作:
@user = User.find(params[:id])
由于您正在深入了解CanCan,我强烈建议您通过their documentation阅读load_and_authorize_resource
方法。你在你的控制器中使用它到D.R.Y.加载要使用的对象或集合的重复代码。它使用您所在的控制器名称和:id
中的params
值来自动实例化您的资源。因此,在您的show
,edit
和update
方法中,它会在@user
和UsersController
中实例化单个index
对象方法,它将实例化集合@users
。
FWIW,您可能想知道为什么您没有看到NoMethodError
行if needs_password?(@user, user_params)
突然出现。即使在那里使用了@user
,如果你查看needs_password?
方法的定义,它需要一个user
参数,但实际上并没有使用它,所以它赢了&# 39; t抱怨@user
在被叫时是{n}的事实。但是,在此行@user.update_without_password(user_params)
中,您直接将update_without_password
方法/消息发送到@user
变量,即nil
。
我希望有所帮助!