Skip to content

Commit 8b258e4

Browse files
Allow associations to be cast/put inside of embedded schema changesets (#4504)
1 parent 02e6918 commit 8b258e4

File tree

3 files changed

+4
-52
lines changed

3 files changed

+4
-52
lines changed

lib/ecto/changeset.ex

+2-20
Original file line numberDiff line numberDiff line change
@@ -1197,16 +1197,7 @@ defmodule Ecto.Changeset do
11971197
11981198
"""
11991199
@spec cast_assoc(t, atom, Keyword.t()) :: t
1200-
def cast_assoc(changeset, name, opts \\ [])
1201-
1202-
def cast_assoc(%Changeset{data: %{} = data}, _name, _opts)
1203-
when not is_map_key(data, :__meta__) do
1204-
raise ArgumentError,
1205-
"cast_assoc/3 cannot be used to cast associations into embedded schemas or schemaless changesets. " <>
1206-
"Please modify the association independently."
1207-
end
1208-
1209-
def cast_assoc(changeset, name, opts) when is_atom(name) do
1200+
def cast_assoc(changeset, name, opts \\ []) when is_atom(name) do
12101201
cast_relation(:assoc, changeset, name, opts)
12111202
end
12121203

@@ -2104,16 +2095,7 @@ defmodule Ecto.Changeset do
21042095
21052096
"""
21062097
@spec put_assoc(t, atom, term, Keyword.t()) :: t
2107-
def put_assoc(changeset, name, value, opts \\ [])
2108-
2109-
def put_assoc(%Changeset{data: %{} = data}, _name, _value, _opts)
2110-
when not is_map_key(data, :__meta__) do
2111-
raise ArgumentError,
2112-
"put_assoc/4 cannot be used to put associations into embedded schemas or schemaless changesets. " <>
2113-
"Please modify the association independently."
2114-
end
2115-
2116-
def put_assoc(%Changeset{} = changeset, name, value, opts) do
2098+
def put_assoc(%Changeset{} = changeset, name, value, opts \\ []) do
21172099
put_relation(:assoc, changeset, name, value, opts)
21182100
end
21192101

lib/ecto/schema.ex

+2-7
Original file line numberDiff line numberDiff line change
@@ -549,13 +549,8 @@ defmodule Ecto.Schema do
549549
`@primary_key` attribute.
550550
551551
`belongs_to/3` associations may be defined inside of
552-
embedded schemas. However, they are essentially read-only.
553-
This means you may preload the associations but you may
554-
not modify them by using `Ecto.Changeset.cast_assoc/3`
555-
or `Ecto.Changeset.put_assoc/4`. If you would like to
556-
modify the associations of an embedded schema, you must
557-
change them independently. Associations nested inside of
558-
embedded schemas will also not be persisted to the database
552+
embedded schemas. However, any association nested inside
553+
of an embedded schema won't be persisted to the database
559554
when calling `c:Ecto.Repo.insert/2` or `c:Ecto.Repo.update/2`.
560555
"""
561556
defmacro embedded_schema(do: block) do

test/ecto/changeset/belongs_to_test.exs

-25
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,6 @@ defmodule Ecto.Changeset.BelongsToTest do
4949
end
5050
end
5151

52-
defmodule Embed do
53-
use Ecto.Schema
54-
55-
embedded_schema do
56-
belongs_to :profile, Profile
57-
end
58-
end
59-
6052
defp cast(schema, params, assoc, opts \\ []) do
6153
schema
6254
|> Changeset.cast(params, ~w())
@@ -328,14 +320,6 @@ defmodule Ecto.Changeset.BelongsToTest do
328320
assert changeset.valid?
329321
end
330322

331-
test "cast belongs_to from embedded schema" do
332-
msg = ~r"cast_assoc/3 cannot be used to cast associations into embedded schemas"
333-
334-
assert_raise ArgumentError, msg, fn ->
335-
cast(%Embed{}, %{"profile" => %{"name" => "michal"}}, :profile)
336-
end
337-
end
338-
339323
## Change
340324

341325
test "change belongs_to" do
@@ -503,15 +487,6 @@ defmodule Ecto.Changeset.BelongsToTest do
503487
refute Map.has_key?(changeset.changes, :profile)
504488
end
505489

506-
test "put_assoc/4 from embedded schema" do
507-
msg = ~r"put_assoc/4 cannot be used to put associations into embedded schema"
508-
base_changeset = Changeset.change(%Embed{})
509-
510-
assert_raise ArgumentError, msg, fn ->
511-
Changeset.put_assoc(base_changeset, :profile, %{name: "michal"})
512-
end
513-
end
514-
515490
test "put_assoc/4 with empty" do
516491
# On unloaded
517492
changeset =

0 commit comments

Comments
 (0)