Ruby on Rails: sind auf einer polymorphen Verbindung mit Submodellen
Frage
Wenn Sie mit einer polymorphen Assoziation arbeitet, ist es möglich, eine Include auf Submodellen auszuführen, die in einigen Arten nur vorhanden sind?
Beispiel:
class Container
belongs_to :contents, :polymorphic => true
end
class Food
has_one :container
belongs_to :expiration
end
class Things
has_one :container
end
In der Ansicht werde ich möchte so etwas wie zu tun:
<% c = Containers.all %>
<% if c.class == Food %>
<%= food.expiration %>
<% end %>
Daher würde ich die Abläufe zu eifrig Last, wie wenn ich c laden, weil ich weiß, ich werde jeden einzelnen von ihnen benötigen. Gibt es eine Möglichkeit, dies zu tun? Nur eine regelmäßige definieren. Umfassen wird mir Fehler, weil nicht alle geschlossenen Typen ein submodel Ablauf haben
Lösung
Edited Antwort
Vor kurzem fand ich heraus, dass Rails eifrig Laden von polymorphen Assoziationen unterstützt, wenn Sie durch die polymorphen Typ Spalte filtern. So gibt es keine Notwendigkeit zu erklären, gefälschte Assoziationen.
class Container
belongs_to :content, :polymorphic => true
end
Jetzt abfragen, um die Container
von 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)
Alt Antwort
Dies ist ein Hack, da es keine direkte Möglichkeit ist es, die polymorphen Objekte in einer Abfrage.
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
Jetzt abfragen, um die Container
von 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)
Das ergibt zwei SQL-Aufrufe an die Datenbank (eigentlich ist es 4 Anrufe als Schienen führt eine SQL für jeden :include
)
Es gibt keine Möglichkeit, dies in einer SQL zu tun, wie Sie für verschiedene Inhaltstypen unterschiedlichen Spaltensatz benötigen.
Caveat:. Die Dummy-Verbände auf Content
Klasse sollte nicht direkt verwendet werden, da es zu unerwarteten Ergebnissen führt
Z. B:. Nehmen wir das erste Objekt in der contents
Tabelle enthält Lebensmittel
Content.first.food # will work
Content.first.thing
Der zweite Anruf wird nicht funktionieren. Es könnten Sie ein Thing
Objekt mit derselben ID wie das Food
Objekt durch Content
hingewiesen.