Using Ecto for tables referencing themselves

I am trying to persist my data about tasks for a project management app I am developing. As you know, a project consists of tasks, and these tasks have dependencies on other tasks.

So far, I have done this:

defmodule Mgmt.Task do
  use Ecto.Schema

  schema "tasks" do
    field :duration, :float
    has_many :tasks, Mgmt.Task
    field :start_date, :date
    field :end_date, :date
    field :act_duration, :float
    field :act_start_date, :date
    field :act_end_date, :date
    field :complete, :float
    field :status, :string

I have the following questions for my situation:

  1. In the code snippet above, the has_many part represents the dependencies of a task on other tasks. I would like to be able to have this piece of information as a field (say, :deps). I am wondering how to tell Ecto that this (has_many), is a field as well.
  2. How to define my migration file (for the very first creation of tasks table). What should I put in the ??? below
defmodule Mgmt.Repo.Migrations.CreateTasks do
  use Ecto.Migration

  def change do
    create table(:tasks) do
      add(:duration, :float)
      add(:start_date, :date)
      add(:end_date, :date)
      add(:act_duration, :float)
      add(:act_start_date, :date)
      add(:act_end_date, :date)
      add(:complete, :float)
      add(:status, :string)

Many thanks

I would have an additional table inbetween the tasks, e.g. TaskToTaskRelationship, which acts like a join table. This table can have fields to annotate the relationship between the tasks e.g. split_from, depends_on, blocked_by etc.

  1. In your example you created a field called tasks which is this has_many relationship.
  2. You don’t have to specify anything in the migration file. Ecto will magically fill in this field for you when you read from the database.

The migration file details how the physical database should look (i.e. what is actually stored on disk), the schema details how to map from physical database to application model (i.e. what is presented to your application).

They explain many_to_many here:

But you probably has more success with has_many through