CanCan:检查记录的权限,包括依赖性

时间:2015-02-26 10:29:10

标签: ruby-on-rails cancan cancancan

示例模型

  • 用户在0 .. *车库
  • 每辆车都在一个车厢里
  • 每辆汽车皮卡都有1辆汽车

权限设置

can :read, Car, :car_pool => { :users => { :id => user.id } }
can :create, CarPickup

用例

目标是让用户为他的一辆车创建一个新的CarPickup。该视图可能看起来像是:

= form_for @car_pickup do
  = f.association :car, :collection => Car.accessible_by(current_ability)

问题

保存用户时,应验证当前用户是否可以访问通过上述表单传递的汽车。是否有一种优雅的方式来做一些事情:

def create
  @car_pickup = CarPickup.new(params[:car_pickup])

  authorize :create, @car_pickup

  if @car_pickup.car
    Car.accessible_by(current_ability).include?(@car_pickup.car)
  end

  if @car_pickup.save
  # ...
end

解决方案尝试/进一步的问题

  • 适应能力如下:

    can :read, Car, :car_pool => { :users => { :id => user.id } }
    can :create, CarPickup, :car => { :car_pool => { :users => { :id => user.id } } }
    

    如果在未选择产品的情况下保存表单,则会中断。对于此解决方案,需要有一种方法来指定如果不是nil

  • 第二次授权电话:

    authorize! :read, @car_pickup.car if @car_pickup.car
    
  • 可以将can?(:read, @car_pickup)理解为单个记录的accessible_by吗?

  • 这可能是使用load_resource实现的吗?

1 个答案:

答案 0 :(得分:0)

刚刚找到解决方案,这非常简单:

can :read, Car, :car_pool => { :users => { :id => user.id } }
can :create, CarPickup, :car => { :car_pool => { :users => { :id => user.id } }

# Add this line in order for it to work when trying to save a
# `CarPickup` without any `Car`.
can :create, CarPickup, :car => nil