На полиморфных c ассоциациях можно ли использовать несколько типов источников для одного has_many через запрос? - PullRequest
0 голосов
/ 17 марта 2020

При работе с полиморфными c ассоциациями возможно ли иметь запрос has_many through, который извлекает ВСЕ доступные типы source_types?

Насколько я понимаю, на данный момент каждый тип источника нуждается в собственном методе запроса, так как Я показываю здесь в модели изображения

image.rb

has_many :image_tags
has_many :tags, through: :image_tags, source: :taggable, source_type: 'Tag'
has_many :people, through: :image_tags, source: :taggable, source_type: 'Person'
has_many :businesses, through: :image_tags, source: :taggable, source_type: 'Business'
...

tag.rb

has_many :image_tags, as: :taggable
has_many :images, through: :image_tags

image_tag.rb

belongs_to :image
belongs_to :taggable, polymorphic: true

def build_taggable(params)
  self.taggable = taggable_type.constantize.new(params)
end

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

Просто подумайте вслух, может ли это привести к созданию какого-то необработанного SQL объединения, которое будет действовать непосредственно на таблицу ImageTags? Или есть более Railsy / ActiveRecordy способ приблизиться к нему?


ОБНОВЛЕНИЕ 20200319:

С тех пор я нашел способ объединения отдельных методов, но это все еще требует создания уникальных методов.

def taggables 
  tags + people + businesses
end

Это позволяет что-то вроде

i = Image.first
i.crops.map(&:taggables)

Еще не совсем ответ, но пока что это временный обходной путь.

1 Ответ

0 голосов
/ 17 марта 2020

Вы можете использовать запрос ниже, чтобы получить любую ассоциацию, которая прикреплена к image_tag :

# get all images with all associations
imgs = Image.includes(image_tags: :taggable)

# to get value polymorphic association regardless of it's source
# taggable may be tags, people or businesses
poly_assoc = imgs.first.taggable # associaiton of first record
# to get the association type
pp pol_assoc.to_s.class.to_s
...