2015-05-16 15 views
17

Ecto scheint die polymorphe Assoziation zu unterstützen, da ich https://github.com/elixir-lang/ecto/issues/389 und die damit verbundenen Probleme durchgelesen habe.Wie funktioniert die polymorphe Assoziation mit Ecto?

Angenommen, ich brauche eine Kommentarmodellzuordnung zu Aufgaben- und Ereignismodellen. Wenn mein Verständnis von Ecto Verbindung mit benutzerdefinierter Quelle richtig ist, dann brauchen wir vier Tische und drei Modelle,

Tabellen

  • Aufgaben
  • Ereignisse
  • tasks_comments
  • events_comments

Modell

  • Aufgabe
  • Ereignis
  • Kommentar

Aufgaben- und Ereignismodell wird, wie unten die has_many Verbindung mit benutzerdefinierter Quelle hat.

defmodule ExampleApp.Task do 
    use ExampleApp.Web, :model 

    schema "tasks" do 
    field :title, :string 
    field :body, :string 
    has_many :comments, {"tasks_comments", Comment} 

    timestamps 
    end 
end 

defmodule ExampleApp.Event do 
    use ExampleApp.Web, :model 

    schema "events" do 
    field :title, :string 
    field :body, :string 
    has_many :comments, {"events_comments", Comment} 

    timestamps 
    end 
end 

Nun, was ich nicht verstehe, ist, wie der Kommentar Modell aussehen sollte?

Wie behandelt das Kommentarmodell zwei Tabellen? und wie geht es mit der Zugehörigkeit zu den verschiedenen Modellen um?

Antwort

17

Wenn Sie mit dem obigen Entwurf gehen, hat das Kommentarmodell keine Tabelle wirklich, seine Tabelle wird durch die Zuordnung definiert. So erhalten alle Kommentare für alle Veranstaltungen können Sie tun:

from c in {"events_comments", Comment} 

Dies ist eine großartige Technik, die in einigen Fällen und ermöglicht es Ihnen, zu kuppeln die Speicherung (die Tabelle) mit dem Modell. Sie können dasselbe Modell für verschiedene Tabellen verwenden.

Wenn Sie jedoch alle Kommentare abrufen und sie sowohl Ereignissen als auch Aufgaben zuordnen möchten, können Sie sie über Beziehungen verwenden. Sie haben "Ereignisse" < -> "events_comments" < -> "Kommentare" und "Aufgaben" < -> "Aufgaben_Kommentare" < -> "Kommentare".

Ein anderer Ansatz besteht darin, mit Rails-Methoden polymorphe Assoziationen zu machen und eine "Art" -Spalte im Kommentarmodell zu definieren. Es bricht die Datenbankreferenzen, aber es ist eine andere Möglichkeit, dies anzugehen.

Ich werde Ecto docs in dieser Sache verbessern, danke für die Rückmeldung!

+0

Jose, danke für die Antwort. Aus Ihren Antworten ergeben sich mehrere Fragen. Vielleicht ist das alles trivial. 1. "Das Kommentarmodell hat keine Tabelle" => Wie funktioniert das Kommentarmodell ohne Schema? Ich lese 'Schema == Tabelle'. Wie kann ich Kommentar ohne Schema und damit ohne Changesets validieren? 2. Wie funktioniert der 'rails way' in Ecto association? Gibt es einen Beispielcode? Ich sehe den Quellcode oder die Dokumente, die dies unterstützt, nicht. – shankardevy

+1

1.Das Kommentarmodell hat keine Tabelle, aber es hat eine, wenn es über die Assoziation erstellt wird. Also ist es das Geheimnis, 'assoc (task,: comments)' und niemals '% Comment {}' zu verwenden. Ich habe die hier dokumentiert: https://github.com/elixir-lang/ecto/commit/1d98ad795b8707ff8a9496657112603c14a64cc2 –

+1

2. Die Schienen Weg nicht in Ecto Verbänden funktioniert, weil es in der Regel eine schlechte Praxis ist, da die Datenbank nicht seine Referenzen halten. Sie müssten Ihre Abfragen erstellen und die richtigen Felder von Hand festlegen. –

Verwandte Themen