【问题标题】:With CanCan, how do i limit ability based on association / child attribute使用CanCan,我如何根据关联/子属性限制能力
【发布时间】:2023-10-04 22:37:01
【问题描述】:

我有一个数据库设置,其中有很多用户,这些用户具有成员或管理员的角色。每个用户有许多汽车。每辆车都有很多时间片

那么,只有当用户是母车的车主时,我如何限制用户编辑时间记录的能力。

在CanCan:

class Ability
    include CanCan::Ability

    def initialize(user)
        user ||= User.new # guest user (not logged in)
        if user.has_role? :admin
            can :manage, :all
        elsif user.has_role? :member
            can :manage, Car, :user_id => user.id
            can :manage, Timeslip, :car => {:user_id => user.id}
        end
    end
end

所以can :manage, Timeslip, :car => {:user_id => user.id} 是我需要帮助的地方。

因为 Timeslip 是 Car 的关联/孩子,我需要检查其父 car.user_id = Cancan user.id

我认为我写这篇文章的方式符合 CanCan 文档,但我哪里出错了?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 postgresql cancan rails-activerecord


    【解决方案1】:

    可能有更短的方法来编写它,但这会起作用:

    can :manage, Timeslip do |timeslip|
         timeslip.car.user_id == user.id
    end
    

    【讨论】:

    • 我收到undefined method "user_id" for nil:NilClass
    • 这意味着你有一个没有与之关联的汽车的时间轴。
    • 我把它改成了can [:edit,:update,:destroy], Timeslip do |timeslip| timeslip.user == user end,它现在可以工作了。我正在使用我的 has_one :user, :through => :car 出于某种原因,它没有找到汽车关联?但我可以通过调试看到它...不知道
    【解决方案2】:

    这对我有用:can :manage, Timeslip, car: { roles: { id: user.role_ids } }

    【讨论】: