簡體   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