has_many, through associations in Ecto
<p>I'm still trying to grok how to deal with creating/updating <code>has_many, through:</code> associations in <a href="https://hexdocs.pm/ecto/Ecto.html" rel="nofollow noreferrer">Ecto</a>. I've re-read <a href="http://blog.plataformatec.com.br/2015/08/working-with-ecto-associations-and-embeds/" rel="nofollow noreferrer">José's</a> post on associations as well as <a href="https://hexdocs.pm/ecto/Ecto.Schema.html#has_many/3" rel="nofollow noreferrer">the docs</a>, but I'm still struggling.</p>

<p>What I have is this:</p>

<p><strong>web/models/dish.ex</strong></p>

<pre><code>defmodule Mp.Dish do
  use Mp.Web, :model

  schema "dishes" do
    # ...
    has_many :dish_dietary_prefs, Mp.DishDietaryPref, on_delete: :delete_all,
      on_replace: :delete
    has_many :dietary_prefs, through: [:dish_dietary_prefs, :dietary_pref]
  end

  # ...
end
</code></pre>

<p><strong>web/models/dietary_pref.ex</strong></p>

<pre><code>defmodule Mp.DietaryPref do
  use Mp.Web, :model

  schema "dietary_prefs" do
    # ...
    has_many :dish_dietary_prefs, Mp.DishDietaryPref, on_delete: :delete_all,
      on_replace: :delete
    has_many :dishes, through: [:dish_dietary_prefs, :dish]
  end

  # ...
end
</code></pre>

<p><strong>web/models/dish_dietary_pref.ex</strong></p>

<pre><code>defmodule Mp.DishDietaryPref do
  use Ecto.Schema

  schema "dish_dietary_prefs" do
    belongs_to :dish, Mp.Dish
    belongs_to :dietary_pref, Mp.DietaryPref
  end
end
</code></pre>

<p>I have a JSON endpoint that receives parameters for a <code>Dish</code>, inside which I have a key called <code>dietary_prefs</code> that is passed as a comma-delimited string, so, for example:</p>

<pre><code>[info] POST /api/vendors/4/dishes
[debug] Processing by Mp.Api.DishController.create/2
  Parameters: %{"dish" =&gt; %{"dietary_prefs" =&gt; "2,1"}, "vendor_id" =&gt; "4"}
</code></pre>

<p>(With additional parameters for <code>"dish"</code> removed for this SO post.)</p>

<hr>

<p>How do I handle this in my controller? Specifically, I want this behavior:</p>

<ol>
<li>For <code>POST</code> requests (create actions), create the necessary records in <code>dish_dietary_prefs</code> to associate this new <code>Dish</code> with the given <code>DietaryPref</code>s. The comma-delimited string are <code>id</code>s for <code>DietaryPref</code> records.</li>
<li>For <code>PUT/PATCH</code> requests (updates), create/destroy the necessary records in <code>dish_dietary_prefs</code> to update the associations (users can re-assign dishes to different dietary prefs).</li>
<li>For <code>DELETE</code> requests, destroy <code>dish_dietary_prefs</code>. I think this case is already handled with the <code>on_delete</code> configuration in the models.</li>
</ol>

<p>I already have the logic in my controller to create/update dishes for a given vendor (which is just a simple <code>has_many/belongs_to</code> relationship), but I still can't figure out how to create/update/destroy these associations for a given dish.</p>

<p>Any help would be greatly appreciated.</p>

<hr>

<p>If I will <a href="https://stackoverflow.com/a/33136129/32154">"need to receive the IDs and manually build the intermediate association for each"</a> <code>DietaryPref</code> I am associating to the <code>Dish</code>, could I get an example of how I would do that to the above specification in my controller?</p>

<hr>

<p><strong><em>UPDATE</em></strong>: Just seeing that Ecto 2.0.0-beta.1 is out, and that is <a href="https://github.com/elixir-lang/ecto/blob/v2.0.0-beta.0/CHANGELOG.md#many-to-many" rel="nofollow noreferrer">supports <code>many_to_many</code></a>, which looks like it would be a solution to my problem. Anyone have an example of using it in action, like I've described above?</p>