2015-05-16 6 views
17

Ecto sembra supportare l'associazione polimorfica durante la lettura di https://github.com/elixir-lang/ecto/issues/389 e dei relativi problemi ad esso collegati.Come funziona l'associazione Polymorphic con Ecto?

Supponiamo di aver bisogno di un'associazione modello Comment su modelli Task ed Event. Se la mia comprensione dell'associazione Ecto con fonte personalizzato è giusto, allora abbiamo bisogno di quattro tabelle e tre i modelli,

Tabelle

  • compiti
  • eventi
  • tasks_comments
  • events_comments

Modello

  • Task
  • Evento
  • commento

task ed eventi modello avrà l'associazione has_many con fonte personalizzata come di seguito.

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 

Ora quello che non capisco è come il modello di commento dovrebbe essere simile?

In che modo il modello Commento gestisce due tabelle? e come gestisce l'appartenenza all'associazione ai diversi modelli?

risposta

17

Se si utilizza il modello precedente, il modello di commento non ha alcuna tabella, la sua tabella è definita dall'associazione. Quindi, per ottenere tutti i commenti per tutti gli eventi, si può fare:

from c in {"events_comments", Comment} 

Questa è una grande tecnica, in alcuni casi e ti permette di non accoppiare lo stoccaggio (tavolo) con il modello. È possibile utilizzare lo stesso modello per tabelle diverse.

Tuttavia, se si desidera recuperare tutti i commenti e associarli a eventi e attività, è possibile utilizzare le relazioni. Avrai "eventi" < -> "events_comments" < -> "commenti" e "attività" < -> "tasks_comments" < -> "commenti".

Un altro approccio è quello di utilizzare il metodo Rails per creare associazioni polimorfiche e definire una colonna "tipo" nel modello Commento. Rompe i riferimenti al database, ma è un altro modo per affrontarlo.

Migliorerò i documenti Ecto sull'argomento, grazie per il feedback!

+0

Jose, grazie per aver risposto. Ci sono più domande derivanti dalle tue risposte. Forse questo è tutto banale. 1. "il modello di commento non ha alcuna tabella" => come funziona il modello di commento senza schema. Sto leggendo 'schema == tabella'. Come posso convalidare i commenti senza schema e quindi senza changeset? 2. In che modo il "senso delle rotaie" funziona nell'associazione Ecto? c'è qualche codice di esempio? Non vedo la lettura del codice sorgente o dei documenti che questo è supportato. – shankardevy

+1

1.Il modello di commento non ha una tabella ma ne ha uno quando viene creato tramite l'associazione. Quindi il segreto è usare 'assoc (task,: comments)' e mai '% Comment {}'. Ho documentato quelli qui: https://github.com/elixir-lang/ecto/commit/1d98ad795b8707ff8a9496657112603c14a64cc2 –

+1

2. Il modo rotaie non funziona nelle associazioni Ecto perché in genere è una cattiva pratica perché il database non può mantenere i suoi riferimenti. Dovresti compilare le tue query e impostare manualmente i campi appropriati. –