简体   繁体   English

私有方法`update_without_password'调用了nil:NilClass

[英]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 . 因此,在showeditupdate方法中,它将实例化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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM