Вопрос

При работе с полиморфной ассоциацией можно ли запустить включение на подмодельки, которые присутствуют только в некоторых типах?

Пример:

class Container
  belongs_to :contents, :polymorphic => true
end
class Food
  has_one :container
  belongs_to :expiration
end
class Things
  has_one :container
end

В поле зрения я хочу сделать что-то вроде:

<% c = Containers.all %>
<% if c.class == Food %>
  <%= food.expiration %>
<% end %>

Поэтому я хотел бы стремиться загрузить скорость, когда я загружаю C, потому что я знаю, что мне понадобится каждый последний из них. Есть ли способ сделать это? Просто определяя регулярное: включить, получает мне ошибки, потому что не все прилагаемые типы имеют срок действия подмодера.

Это было полезно?

Решение

Отредактированный ответ

Недавно я узнал, что 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top