Ecto seems to support polymorphic association as I read through https://github.com/elixir-lang/ecto/issues/389 and its related issues linked from it.
Let's say I need a Comment model association on Task and Event models. If my understanding of Ecto association with custom source is right, then we need four tables and three models,
Tables
Model
Task and Event model will have the has_many association with custom source as below.
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
Now what I don't understand is how should the Comment model look like?
How does the Comment model handle two table? and How does it handle belongs_to association to the different models?
If you are going with the design above, the comment model does not really have any table, its table is defined by the association. So to get all comments for all events, you can do:
from c in {"events_comments", Comment}
This is a great technique in some cases and it allows you to not couple the storage (the table) with the model. You can use the same model for different tables.
However, if you want to fetch all comments and associate them with both events and tasks, then you could use through relationships. You will have "events" <-> "events_comments" <-> "comments" and "tasks" <-> "tasks_comments" <-> "comments".
Another approach is to go with Rails way of doing polymorphic associations and defined a "kind" column in the Comment model. It does break the database references but it is another way to tackle this.
I will improve Ecto docs on the matter, thanks for the feedback!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With