如何检查值是否在 CanCanCan 条件散列的数组中

How to check if value is in array on CanCanCan hash of conditions

我有三个模型 类:PatientBoardMedicationCustomer,它们之间的关系如下:

患者委员会

associations do 
      has_and_belongs_to_many :customers
      has_many :medications
end

用药

associations do 
      belongs_to :patient_board
end

客户

associations do 
      has_many :patient_boards
end

由于has_and_belongs_to_many的关系,我的patient_board对象是这样的:

{
  _id: ObjectId("5e160f235eb3607d57f59341"), 
  name: "test",
  customer_ids: [ObjectId("5db1e6f45eb36059a4d98e7f")]
}

可以访问该患者面板的所有客户的 ID 将位于 customer_ids 数组中。

问题

当尝试为用户设置权限时,我为 PatientBoard 做了如下操作:

can :manage, PatientBoard do |pb|
    pb.customer_ids.include? user.id
end

大部分情况下都有效。但是 create 方法仍然不起作用,所以我也不得不插入以下行:

can :create, PatientBoard

现在它可以正常工作了,但是当我尝试对 Medication 做同样的事情时它没有工作:

can :manage, Medication do |m|
    m.patient_board.customer_ids.include? user.id
end

它抛出此错误消息:

The accessible_by call cannot be used with a block 'can' definition. The SQL cannot be determined for :index Medication

所以我尝试这样做:

can :manage, Medication, patient_board: { customers: { id: user.id } }

这样就不会再显示错误消息,但也不会显示药物。当尝试创建一种新药物时,它会抛出该错误:

undefined method `matches?' for #PatientBoard:0x007f663c38d0e8 Did you mean? _matches? matcher

我认为这是有道理的,因为它试图将字符串值 (user.id) 与数组值 (customer_ids)

进行比较

简历中

如何使用 CanCanCan 的条件散列来检查 user.id 是否在 customer_ids 数组中?

看起来 include? 正在 can 块内触发 sql 查询。尝试将 customer_ids 转换为数组:

can :manage, Medication do |m|
  m.patient_board.customer_ids.to_a.include? user.id
end

所以,我在CanCan github.

上检查了issue #345后成功解决了问题。

显然,我必须提供一个 sql 查询来匹配药物,所以我这样做了:

can [:manage], [Medication], ["#{user.id} in ( select customer_ids from patient_board where id = medications.patient_board.id ) )"] do |t|
   t.patient_board.customer_ids.include? user.
end