繁体   English   中英

CanCanCan:如何处理在Ability模型中为零的对象?

[英]CanCanCan: How to handle an object that is nil in Ability model?

我有这个控制器:

class UsersController < ApplicationController
  load_and_authorize_resource

  def create
    @user.save
    respond_with @user
  end

  def update
    @user.update user_params
    respond_with @user
  end

  def destroy
    @user.destroy
    respond_with @user
  end

  private

  def user_params
    permitted_keys = [:name,
                      :email,
                      :password,
                      :password_confirmation,
                      :lock_version]

    permitted_keys << :role if can? :edit_role, @user

    params.require(:user).permit(permitted_keys)
  end
end

在我的能力模型中:

    can :edit_role, User do |user|
      user.new_record?
    end

问题是,在创建用户( #new#create动作)时, @usernil 所以角色不能被设置,因为它不会被添加到permitted_keys#create

如何解决呢? 我可以将控制器更改为:

permitted_keys << :role if action_name == 'create'

但是我不喜欢这样,因为测试Ability比这容易得多。

另一个解决方法是:

permitted_keys << :role if can? :edit_role, @user || User.new

但这感觉多余。

有人有更好的主意吗? 顺便说一句-我很惊讶将nil作为对象传递给can? 是允许的,不会引发错误。 似乎它甚至没有传播到Ability的实际配置,否则为user.new_record? 会引发NoMethod错误或类似错误。

CanCan docs规定了使用块定义功能的方式与您的操作方式略有不同。 他们建议针对您描述的情况(当实例为nil时)使用防护而不是块:

# don't do this
can :edit_role, User do |user|
  user.new_record? # this won't be called for User.accessible_by(current_ability, :edit_role)
end

# do this
can :edit_role, User if user.new_record?

我会尝试的。 有关其他信息,并查看我在哪里获得此示例, 请查看以下文档

似乎使用CanCanCan gem,在创建@user变量之前调用了user_params方法。 user_params是因为需要user_params来创建@user变量,或者至少需要从表单中分配值。

如果CanCanCan在分配表单中的值之前会分配一个新的@user变量(当然是User类型),那么以下代码将在#create#create

private

def user_params
  permitted_keys = [:name,
                    :email,
                    :password,
                    :password_confirmation]

  permitted_keys << :role     if can? :edit_role,    @user
  permitted_keys << :disabled if can? :disable_user, @user

  params.require(:user).permit permitted_keys
end

但是由于它显然没有做到这一点,因此以下变通办法对我有效:

private

def user_params
  permitted_keys = [:name,
                    :email,
                    :password,
                    :password_confirmation]

  auth_object = @user || User.new
  permitted_keys << :role     if can? :edit_role,    auth_object
  permitted_keys << :disabled if can? :disable_user, auth_object

  params.require(:user).permit permitted_keys
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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