Могу ли я создать ассоциацию activerecord через отношение activerecord (при использовании наследственного камня)?

Я использую гем предков в своем проекте rails для создания иерархии групп. Группа может принадлежать родительской группе и может иметь множество дочерних групп. В каждой группе может быть много пользователей, принадлежащих к группе. Модель выглядит так:

class Group < ActiveRecord::Base
  has_ancestry

  has_many :users
end

Я хотел бы иметь возможность получить всех пользователей для потомков группы, что-то вроде этого:

class Group < ActiveRecord::Base
  has_ancestry

  has_many :users
  has_many :descendants_users, through: :descendants
end

что, конечно же, не работает.

Какие-либо предложения?


person George Bailey    schedule 26.10.2012    source источник
comment
если вы хотите получить пользователей группы, просто вызовите group.users? насколько я понял ваш пост, потомки_пользователей не нужны   -  person BvuRVKyUVlViVIc7    schedule 29.10.2012


Ответы (2)


Определите такой метод в своей модели группы.

def descendants_users
    User.joins(:groups).where(:group_id => self.subtree_ids) # Use descendant ids if you dont't want 'self' users
end

Это выполнит 1 запрос для получения идентификаторов поддеревьев и 1 запрос для получения пользователей, и результатом будет уже набор отдельных пользователей.

person Rahul garg    schedule 06.02.2013
comment
Это хороший ответ - он просто запускает один запрос. - person Sam Starling; 08.11.2014
comment
В моей модели категорий... у меня есть def all_products Product.joins(:categories).where(categories:{id:self.subtree_ids}) end, и я получаю дубликаты . это не отдельный набор - person Joel Grannas; 07.04.2015

Может быть, вам просто нужно определить метод, который возвращает всех пользователей-потомков. Таким образом, ваша модель может выглядеть так:

  class Group < ActiveRecord::Base
    has_ancestry

    has_many :users

    def descendants_users
      self.subtree.map(&:users).flatten.compact.uniq
    end
  end
person bazuka    schedule 06.02.2013
comment
Это выполняет запрос для каждой группы отдельно (представьте, что внутри поддерева себя большое количество групп) с последующими итерациями для очистки и удаления отдельных данных. Смотрите мой ответ для оптимизированного способа для этого. - person Rahul garg; 06.02.2013