【问题标题】:private method `update_without_password' called for nil:NilClass为 nil 调用私有方法“update_without_password”:NilClass
【发布时间】:2016-02-21 17:28:31
【问题描述】:

我关注 this tutorial 进行 cancancan 身份验证,特别希望管理员无需密码即可更新用户。我也看到了this 的建议,但我不确定如何将它应用到我自己的代码中。当我单击更新时,它显示“UsersController#update 中的 NoMethodError”私有方法“update_without_password”调用 nil:NilClass

我的应用返回所有用户的参数,所以我不明白这里发生了什么。对 Rails 还是很陌生 - 如果您需要任何进一步的信息,请告诉我。提前谢谢!

用户控制器

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 %>

我在这里缺少什么?请让我知道是否应该提供其他任何东西。谢谢!!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 authentication devise cancancan


    【解决方案1】:

    在我看来,您看到了该错误,因为 @user 没有在 update 方法中实例化。您需要将 @user 设置为您的 User 模型的实例。如果没有看到您的完整应用程序,我无法确定,但您应该可以访问参数哈希中的 :id,从而允许您设置 @user 执行以下操作:

    @user = User.find(params[:id])

    既然您正在深入研究 CanCan,我强烈建议您通读 their documentation 以了解 load_and_authorize_resource 方法。你在你的控制器中使用它来 D.R.Y.重复代码加载您要使用的对象或集合。它使用您所在的控制器的名称和来自params:id 值来自动实例化您的资源。因此,在您的showeditupdate 方法中,它将在您的UsersController 中实例化单数@user 对象,在您的index 方法中,它将实例化集合@users

    FWIW,您可能想知道为什么您没有看到 NoMethodError 出现在 if needs_password?(@user, user_params) 行上。即使在那里使用了@user,如果您查看needs_password? 方法的定义,它需要一个user 参数,但实际上并没有使用它,因此它不会抱怨@987654344 的事实@ 被调用时为零。但是,在@user.update_without_password(user_params) 这一行中,您直接将update_without_password 方法/消息发送到@user 变量,即nil

    希望对你有帮助!

    【讨论】:

    • 哇,这太简单了,但我每次都忽略了这一点。非常感谢您浏览 - 我所要做的就是添加您所要求的内容 - @user = User.find(params[:id]) 并且它运行良好。
    猜你喜欢
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多