Ответ 1
Отредактированный ответ
Недавно я узнал, что Rails поддерживает загрузку полиморфных ассоциаций при фильтрации по столбцу полиморфного типа. Поэтому нет необходимости объявлять ложные ассоциации.
class Container
belongs_to :content, :polymorphic => true
end
Теперь запросите Container
на container_type
.
containers_with_food = Container.find_all_by_content_type("Food",
:include => :content)
containers_with_thing = Container.find_all_by_content_type("Thing",
:include => :content)
Старый ответ
Это взломать, поскольку нет прямого способа включить полиморфные объекты в один запрос.
class Container
belongs_to :contents, :polymorphic => true
# add dummy associations for all the contents.
# this association should not be used directly
belongs_to :food
belongs_to :thing
end
Теперь запросите Container
на container_type
.
containers_with_food = Container.find_all_by_content_type("Food",
:include => :food)
containers_with_thing = Container.find_all_by_content_type("Thing",
:include => :thing)
Это приводит к двум вызовам SQL в базе данных (на самом деле это 4 вызова, поскольку rails выполняет один SQL для каждого :include
)
Невозможно сделать это в одном SQL, поскольку вам нужен другой набор столбцов для разных типов контента.
Предостережение: Фиктивные ассоциации в классе Content
не должны использоваться напрямую, так как это приведет к неожиданным результатам.
Например: Предположим, что первый объект в таблице contents
содержит пищу.
Content.first.food # will work
Content.first.thing
Второй вызов не будет работать. Это может дать вам объект Thing
с тем же идентификатором, что и объект Food
, на который указывает Content
.