ActiveRecord захватывает общую модель из полиморфной ассоциации

Я ищу лучший способ запрашивать пользователей из двух разных моделей, используемых в полиморфной ассоциации. Вот установка

class Schedule < ApplicationRecord
  belongs_to :announcement

  has_many :targets, dependent: :destroy
  has_many :lists, through: :targets, source: :target, source_type: 'List'
  has_many :accounts, through: :targets, source: :target, source_type: 'Account'
end
class Target < ApplicationRecord
  # belongs_to :announcement
  belongs_to :schedule
  belongs_to :target, polymorphic: true

  delegate :announcement, to: :schedule

end
class List < ApplicationRecord
  belongs_to :account

  has_many :targets, as: :target, dependent: :destroy
  has_many :lists_users
  has_many :users, through: :lists_users
end
class Account < ApplicationRecord
  has_many :announcements, dependent: :destroy
  has_many :targets, as: :target, dependent: :destroy
  has_many :users, dependent: :destroy

end

На данный момент я решаю это, создавая метод внутри модели расписания, который захватывает пользователей следующим образом:

  def subscribers
    targets.map(&:target).map(&:users).flatten.uniq
  end

Я посмотрел на что-то подобное с этим вопросом, но не показалось чтобы решить это.


comment
Где вторая модель, используемая в полиморфной ассоциации?   -  person chumakoff    schedule 09.10.2019
comment
Ожидаете ли вы, что коллекция targets.map(&:target) будет включать экземпляры разных классов, или она должна включать только экземпляры Account?   -  person chumakoff    schedule 09.10.2019
comment
Правильно, target.map(&:target) будет коллекцией объектов Account и List, у обоих этих объектов есть пользователи. Затем конечный продукт должен получить коллекцию объектов User, основанную на пользователях в учетной записи и пользователях в списке.   -  person wkernan    schedule 10.10.2019
comment
Вы должны добавить has_many :targets, as: :target в List, чтобы это было понятно   -  person chumakoff    schedule 10.10.2019
comment
Отредактировано, чтобы показать список с ассоциацией has_many. Возможно, я неправильно понимаю концепцию или использую ее неправильно, но если мне нужно вызвать Schedule.targets и включить эту коллекцию в соответствующие модели, чтобы я мог затем захватить пользователей, связанных с ними, зачем Мне нужен has_many также в списке? Если вы посмотрите на модель расписания, вы увидите, что и учетная запись, и список используются в качестве полиморфных ассоциаций.   -  person wkernan    schedule 11.10.2019
comment
Извините, я не заметил ассоциаций в модели Расписание, поэтому было сложно понять, что такое вторая полиморфная ассоциация.   -  person chumakoff    schedule 11.10.2019


Ответы (1)


Я бы сделал это так:

class Schedule < ApplicationRecord
  def subscribers
    # fetch all associated user IDs
    lists_user_ids = lists.joins(:lists_users).distinct.pluck("lists_users.user_id")
    accounts_user_ids = accounts.joins(:users).distinct.pluck("users.id")
    user_ids = (lists_user_ids + accounts_user_ids).uniq

    # fetch users by IDs
    User.where(id: user_ids)
  end
end
person chumakoff    schedule 10.10.2019