2013-06-07 3 views
3

Я использую CanCan 1.6.10 с Rails 3.2.13Как написать CanCan-способность с соединением?

Я настраиваю свои способности для модели моего персонала (а не пользователя). У меня есть:

class Ability 
    include CanCan::Ability 
    def initialize(staff) 
     if staff.role? :driver 
      can :read, User.joins(:orders => {:delivery_slot => :driver}).where("driver_id = ?", staff.id) 

Я проверил соединения, где в консоли, и он возвращает 7 записей. Когда я проверить способность он не возвращать:

User.accessible_by(Ability.new(Staff.find(7))) 

SQL, из последнего .to_sql запроса показывает, как:

SELECT `users`.* FROM `users` WHERE (1=0) 

тогда User.joins (: заказы => {: delivery_slot => :. водитель}), где ("? driver_id =", 7) дает:

SELECT `users`.* FROM `users` INNER JOIN `orders` ON `orders`.`user_id` = `users`.`id` INNER JOIN `delivery_slots` ON `delivery_slots`.`id` = `orders`.`delivery_slot_id` INNER JOIN `staff` ON `staff`.`id` = `delivery_slots`.`driver_id` WHERE (driver_id = 7) 
+0

Опубликовано решение, можете ли вы проверить, работает ли это? – Subhas

ответ

7

вы пробовали hash of conditions вместо того, явно присоединяется?

can :read, User, :orders=>{:delivery_slot=>{:driver=>{:id => staff.id}}} 
+0

Спасибо @RDX Я думаю, что работает, но он возвращает повторяющиеся результаты - есть ли способ заставить его возвращать только уникальные результаты? –

+1

Я бы предпочел не делать это на уровне CanCan и делать это, когда мы используем 'доступный_by'. то есть «User.accessible_by (Ability.new (Staff.find (7))). uniq'. Соединения автоматически создают повторяющиеся строки, и вместо того, чтобы пытаться ударить головой, разрешая это в CanCan, скорее сделайте это в модели. Вы даже можете создать вспомогательный метод в своей модели, который просто делегирует 'доступный_by' и делает' uniq' автоматически, например 'def доступный_by_uniq (* args) сделать access_by (* args) .uniq end' – Subhas

+1

Спасибо, я создал помощника метод, как вы предложили в модели пользователя, но просто для тех, кто следует за ним, должен быть метод класса класса, а не def self.accessible_by_uniq (* args) Доступный_by (* args) .uniq end –

Смежные вопросы