Как проверить, находится ли значение в массиве на CanCanCan ha sh условий - PullRequest
1 голос
/ 08 января 2020

У меня есть три модельных класса: 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")]
}

Где идентификаторы всех клиентов, имеющих доступ к этой плате пациента, будут находиться внутри массива 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) )

В резюме

Как я могу проверить, находится ли user.id в массиве customer_ids, используя ha sh условий CanCanCan?

Ответы [ 2 ]

0 голосов
/ 09 января 2020

Итак, мне удалось решить проблему после проверки проблемы # 345 на CanCan github.

Очевидно, мне пришлось предоставить запрос 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
0 голосов
/ 08 января 2020

Похоже, include? вызывает запрос sql внутри блока can. Попробуйте преобразовать customer_ids в массив:

can :manage, Medication do |m|
  m.patient_board.customer_ids.to_a.include? user.id
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...