私有方法“update_without_password”调用了 nil:NilClass
private method `update_without_password' called for nil:NilClass
我正在遵循 this tutorial on cancancan authentication, and specifically wanting admins to update users without needing a password. I've also seen this 建议,但不确定如何将其应用到我自己的代码中。当我点击更新时,它说 'NoMethodError in UsersController#update' 私有方法“update_without_password”调用了 nil:NilClass
我的应用程序 returns 所有用户的参数,所以我不明白这里发生了什么。 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 %>
我在这里错过了什么?请让我知道是否应该提供其他任何东西。谢谢!!
在我看来您看到了那个错误,因为 @user
没有在 update
方法中实例化。您需要将 @user
设置为 User
模型的一个实例。没有看到你的完整应用程序,我不能确定,但你应该可以访问参数哈希中的 :id
,允许你设置 @user
做这样的事情:
@user = User.find(params[:id])
由于您正在深入研究 CanCan,我强烈建议您通读 their documentation 以了解 load_and_authorize_resource
方法。你在你的控制器中使用它来 D.R.Y。加载您要使用的对象或集合的重复代码。它使用您所在控制器的名称和 params
中的 :id
值来自动实例化您的资源。因此,在您的 show
、edit
和 update
方法中,它将在您的 UsersController
和 index
中实例化单个 @user
对象] 方法,它将实例化集合 @users
.
FWIW,您可能想知道为什么在 if needs_password?(@user, user_params)
行中看不到 NoMethodError
。即使 @user
在那里使用,如果您查看 needs_password?
方法的定义,它需要一个 user
参数,但实际上并没有使用它,所以它不会抱怨关于 @user
在被调用时为 nil 的事实。但是,在这一行 @user.update_without_password(user_params)
中,您直接将 update_without_password
method/message 发送到 @user
变量,即 nil
.
希望对您有所帮助!
我正在遵循 this tutorial on cancancan authentication, and specifically wanting admins to update users without needing a password. I've also seen this 建议,但不确定如何将其应用到我自己的代码中。当我点击更新时,它说 'NoMethodError in UsersController#update' 私有方法“update_without_password”调用了 nil:NilClass
我的应用程序 returns 所有用户的参数,所以我不明白这里发生了什么。 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 %>
我在这里错过了什么?请让我知道是否应该提供其他任何东西。谢谢!!
在我看来您看到了那个错误,因为 @user
没有在 update
方法中实例化。您需要将 @user
设置为 User
模型的一个实例。没有看到你的完整应用程序,我不能确定,但你应该可以访问参数哈希中的 :id
,允许你设置 @user
做这样的事情:
@user = User.find(params[:id])
由于您正在深入研究 CanCan,我强烈建议您通读 their documentation 以了解 load_and_authorize_resource
方法。你在你的控制器中使用它来 D.R.Y。加载您要使用的对象或集合的重复代码。它使用您所在控制器的名称和 params
中的 :id
值来自动实例化您的资源。因此,在您的 show
、edit
和 update
方法中,它将在您的 UsersController
和 index
中实例化单个 @user
对象] 方法,它将实例化集合 @users
.
FWIW,您可能想知道为什么在 if needs_password?(@user, user_params)
行中看不到 NoMethodError
。即使 @user
在那里使用,如果您查看 needs_password?
方法的定义,它需要一个 user
参数,但实际上并没有使用它,所以它不会抱怨关于 @user
在被调用时为 nil 的事实。但是,在这一行 @user.update_without_password(user_params)
中,您直接将 update_without_password
method/message 发送到 @user
变量,即 nil
.
希望对您有所帮助!