Skip to content

Instantly share code, notes, and snippets.

@julianwachholz
Created July 13, 2018 06:37
Show Gist options
  • Save julianwachholz/c7f94716af86a1e9dc757152e096ee7c to your computer and use it in GitHub Desktop.
Save julianwachholz/c7f94716af86a1e9dc757152e096ee7c to your computer and use it in GitHub Desktop.
Phoenix & Ecto Many-to-Many m2m Relation
<%= form_for @changeset, @action, [multipart: true], fn f -> %>
<!-- ... other fields ... -->
<!-- `selected` accepts only a list of IDs -->
<div class="form-group">
<%= label f, :categories, class: "control-label" %>
<%= multiple_select f, :categories, @categories, selected: Enum.map(@changeset.data.categories, &(&1.id)), class: "form-control" %>
</div>
<% end %>
defmodule Blog.Post do
use Ecto.Schema
import Ecto.Changeset
@required_fields [
:title
]
@optional_fields [
:content
]
schema "posts" do
field(:title, :string)
field(:content, :text)
many_to_many(
:categories,
Blog.Category,
join_through: "post_categories",
on_replace: :delete
)
timestamps(type: :utc_datetime)
end
def changeset(post, attrs) do
post
|> Blog.Repo.preload(:categories)
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
|> put_assoc(:categories, parse_categories(attrs))
end
defp parse_categories(attrs) do
(attrs["categories"] || [])
|> Enum.map(&Blog.get_category!/1)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment