Эликсир экто 2 создай ассоциацию many_to_many

Как я могу установить отношения многие ко многим с ecto 2? В качестве примера приложения я хочу создать пост, который может быть в нескольких категориях. Категории уже существуют. Например:

[%Category{id: "1", name: "elixir"}, %Category{id: "2", name: "erlang"}]

Я использую Ecto 2 beta 0. Пример проекта называется Ecto2.

Я определил две модели:

defmodule Ecto2.Post do
  use Ecto2.Web, :model
  use Ecto.Schema

  schema "posts" do
    field :title, :string
    many_to_many :categories, Ecto2.Category, join_through: "posts_categories", on_replace: :delete
    timestamps
  end

  @required_fields ~w(title)
  @optional_fields ~w()
  def changeset(model, params \\ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
    |> cast_assoc(:categories)  # not suitable?
  end
end

defmodule Ecto2.Category do
  use Ecto2.Web, :model

  schema "categories" do
    field :name, :string

    timestamps
  end

  @required_fields ~w(name)
  @optional_fields ~w()
  def changeset(model, params \\ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
  end
end

Я пытался сделать это так:

post = Repo.get!(Post, 1) |> Repo.preload(:categories)
changeset = Post.changeset(post, %{"title"=> "bla", "categories"=> [%{id: "1"}]})
Repo.update!(changeset)

Но cast_assoc в Post.changeset не подходит для этой задачи, он хочет создать новую категорию вместо ассоциированной. Что я должен использовать вместо этого? build_assoc? Но документы build_assoc не упоминают, что это полезно с many_to_many. Как мне это использовать? Должен ли я поместить build_assoc в Post.changeset тогда, или я должен использовать его в контроллере Phoenix.

Ответы на вопрос(2)

Ваш ответ на вопрос