Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Polymorphic association work with Ecto?

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

  • tasks
  • events
  • tasks_comments
  • events_comments

Model

  • Task
  • Event
  • Comment

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?

like image 298
shankardevy Avatar asked May 16 '15 06:05

shankardevy


1 Answers

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!

like image 90
José Valim Avatar answered Sep 18 '22 20:09

José Valim