[英]private method `update_without_password' called for nil:NilClass
I am following this tutorial on cancancan authentication, and specifically wanting admins to update users without needing a password. 我正在遵循有关cancancan身份验证的教程 ,特别是希望管理员无需密码即可更新用户。 I've also seen this suggestion, but am unsure how to adapt it into my own code. 我也看到了这个建议,但是不确定如何将其改编成自己的代码。 When I click update, it says 'NoMethodError in UsersController#update' private method `update_without_password' called for nil:NilClass 当我单击更新时,它说'UserController中的NoMethodError #update'私有方法`update_without_password'要求nil:NilClass
My app returns all the user's params, so I don't understand what's happening here. 我的应用返回了用户的所有参数,所以我不明白这里发生了什么。 Still very new to rails - let me know if you need any further information. 还是非常陌生的-如果您需要任何进一步的信息,请告诉我。 Thank you in advance! 先感谢您!
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
EDIT FORM 编辑表格
<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 %>
What am I missing here? 我在这里想念什么? Please let me know if should provide anything else. 请让我知道是否应提供其他任何服务。 Thanks!! 谢谢!!
It looks to me like you're seeing that error because @user
is not being instantiated in the update
method. 在我看来,您似乎正在看到该错误,因为@user
未在update
方法中实例化。 You need to set @user
to an instance of your User
model. 您需要将@user
设置为您的User
模型的实例。 Without seeing your full app, I can't know for sure, but you should have access to :id
in the params hash, allowing you to set up @user
doing something like this: 没有看到完整的应用程序,我不确定,但是您应该可以在params哈希中访问:id
,从而可以设置@user
执行以下操作:
@user = User.find(params[:id])
Since you're digging into CanCan, I'd highly encourage you to read through their documentation for the load_and_authorize_resource
method. 由于您正在研究CanCan,因此强烈建议您阅读有关load_and_authorize_resource
方法的文档 。 You use it in your controllers to DRY up repetitive code that loads the object or collection you want to work with. 您可以在控制器中使用它来干燥重复的代码,以加载要使用的对象或集合。 It uses the name of the controller you're in and the :id
value from params
to automatically instantiate your resource. 它使用您所在控制器的名称和params
的:id
值来自动实例化您的资源。 So, in your show
, edit
, and update
methods, it would instantiate the singular @user
object in your UsersController
, and in your index
method, it would instantiate the collection @users
. 因此,在show
, edit
和update
方法中,它将实例化UsersController
的单个@user
对象,在index
方法中,将实例化@users
集合。
FWIW, you might wonder why you aren't seeing the NoMethodError
crop up on the if needs_password?(@user, user_params)
line. FWIW,您可能想知道为什么在if needs_password?(@user, user_params)
行上没有看到NoMethodError
if needs_password?(@user, user_params)
。 Even though @user
is used there, if you look at the definition of your needs_password?
即使在@user
使用@user
,如果您查看needs_password?
的定义needs_password?
method, it takes a user
argument, but doesn't actually use it, so it won't complain about the fact that @user
is nil when it's called. 方法,它需要一个user
参数,但实际上并没有使用它,因此它不会抱怨@user
被调用时为nil的事实。 However, in this line @user.update_without_password(user_params)
, you're directly sending the update_without_password
method/message to the @user
variable, which is nil
. 然而,在该线@user.update_without_password(user_params)
你直接发送update_without_password
方法/消息给@user
变量,它是nil
。
I hope that helps! 希望对您有所帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.