私有方法`update_without_password'呼吁nil:NilClass

时间:2016-02-21 17:28:32

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

我关注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 %>

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

1 个答案:

答案 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值来自动实例化您的资源。因此,在您的showeditupdate方法中,它会在@userUsersController中实例化单个index对象方法,它将实例化集合@users

FWIW,您可能想知道为什么您没有看到NoMethodErrorif needs_password?(@user, user_params)突然出现。即使在那里使用了@user,如果你查看needs_password?方法的定义,它需要一个user参数,但实际上并没有使用它,所以它赢了&# 39; t抱怨@user在被叫时是{n}的事实。但是,在此行@user.update_without_password(user_params)中,您直接将update_without_password方法/消息发送到@user变量,即nil

我希望有所帮助!

相关问题