Как указать ассоциации в Rails, которые проходят через несколько моделей

Я пишу некоторые сложные полиморфные отношения для обработки тегов.

У меня есть модель Tag и модель Tagging, которая принадлежит_полиморфному taggable.

У меня есть модель Item, которая has_many :taggings, :as => :taggable, и has_many :tags, :through => :taggings, так что я могу звонить @item.tags.

Это все работает нормально.

Я хочу добавить еще одну модель — Store, которая has_many :items. Я хочу найти все теги, связанные со всеми товарами в магазине, используя @store.tags.

Вот что у меня есть:

class Store < AR::Base
  has_many :items
  has_many :tags, :through => :items, :source => :taggings

Однако это возвращает все taggings, связанные с элементами в магазине, а не фактические теги.

Как мне указать, что в магазине есть теги has_many, через элементы, через теги?

При необходимости могу опубликовать дополнительную информацию - пытаясь предотвратить информационную перегрузку! Спасибо :)


person nfm    schedule 02.08.2010    source источник


Ответы (2)


Источник для ассоциации has_many должен быть ассоциацией belongs_to, has_one или has_many без параметра :through (спасибо этот ответ для информации).

Существует плагин, с которым некоторые люди добились успеха, но в моем случае он не показался корректно работать с моей taggable полиморфной ассоциацией.

На данный момент мое решение состоит в том, чтобы передать параметр finder_sql в has_many:

class Store < ActiveRecord::Base
  has_many :items
  has_many :tags, :finder_sql => 
    'SELECT tags.* from tags
      INNER JOIN taggings on tags.id = taggings.tag_id
      INNER JOIN items on items.id = taggings.taggable_id AND taggings.taggable_type = "Item"
      WHERE items.store_id = #{id}'

end
person nfm    schedule 05.08.2010

Вы можете сделать это на простом Ruby:

site.wares.map(&:tags).flatten.uniq

Однако это будет неэффективно, если только у вас мало тегов/товаров/предметов.

person François Beausoleil    schedule 02.08.2010