Skip to content

Instantly share code, notes, and snippets.

@ChezCrawford
Created February 11, 2021 18:32
Show Gist options
  • Save ChezCrawford/f6f518e55cde7e407c8988136a602564 to your computer and use it in GitHub Desktop.
Save ChezCrawford/f6f518e55cde7e407c8988136a602564 to your computer and use it in GitHub Desktop.
ecto_validations
defmodule Parent do
use Ecto.Schema
import Ecto.Changeset
schema "parents" do
field :name, :string
embeds_one :child, Child do
field :name, :string
field :age, :integer
end
end
def changeset(schema, params) do
schema
|> cast(params, [:name])
|> cast_embed(:child, with: &child_changeset/2)
end
defp child_changeset(schema, params) do
schema
|> cast(params, [:name, :age])
end
# #Ecto.Changeset<
# action: nil,
# changes: %{
# child: #Ecto.Changeset<
# action: :insert,
# changes: %{age: 3, name: "Jack"},
# errors: [],
# data: #Parent.Child<>,
# valid?: true
# >,
# name: "Charlie"
# },
# errors: [],
# data: #Parent<>,
# valid?: true
# >
def test do
new_parent = %{
name: "Charlie",
child: %{
name: "Jack",
age: 3
}
}
Parent.changeset(%Parent{}, new_parent)
end
# ** (Ecto.CastError) expected params to be a :map, got: `[%{age: 3, name: "Jack"}]`
# (ecto 3.5.7) lib/ecto/changeset.ex:514: Ecto.Changeset.cast/6
# (ecto 3.5.7) lib/ecto/changeset/relation.ex:129: Ecto.Changeset.Relation.do_cast/6
# (ecto 3.5.7) lib/ecto/changeset/relation.ex:318: Ecto.Changeset.Relation.single_change/5
# (ecto 3.5.7) lib/ecto/changeset/relation.ex:113: Ecto.Changeset.Relation.cast/5
# (ecto 3.5.7) lib/ecto/changeset.ex:811: Ecto.Changeset.cast_relation/4
def test_bad_input do
new_parent = %{
name: "Charlie",
child: [%{
name: "Jack",
age: 3
}]
}
Parent.changeset(%Parent{}, new_parent)
end
end
@Adzz
Copy link

Adzz commented Feb 11, 2021

Why would you expect that? You've said it embeds_one not that it embeds_many so it makes sense that it would blow up on a list in the second example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment