我有三个模型类:PatientBoard
,Medication
和Customer
,它们相互关联,如下所示:
PatientBoard
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
我想这很有意义,因为它试图将String值(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