@@ -1265,7 +1265,6 @@ defmodule Ecto.Changeset do
12651265 defp cast_relation ( type , % Changeset { } = changeset , key , opts ) do
12661266 { key , param_key } = cast_key ( key )
12671267 % { data: data , types: types , params: params , changes: changes } = changeset
1268- % { related: related } = relation = relation! ( :cast , type , key , Map . get ( types , key ) )
12691268 params = params || % { }
12701269
12711270 { changeset , required? } =
@@ -1275,7 +1274,8 @@ defmodule Ecto.Changeset do
12751274 { changeset , false }
12761275 end
12771276
1278- on_cast = Keyword . get_lazy ( opts , :with , fn -> on_cast_default ( type , related ) end )
1277+ relation = relation! ( :cast , type , key , Map . get ( types , key ) )
1278+ on_cast = Keyword . get ( opts , :with )
12791279 sort = opts_key_from_params ( :sort_param , opts , params )
12801280 drop = opts_key_from_params ( :drop_param , opts , params )
12811281
@@ -1284,14 +1284,14 @@ defmodule Ecto.Changeset do
12841284 value = Map . get ( params , param_key )
12851285 original = Map . get ( data , key )
12861286 current = Relation . load! ( data , original )
1287- value = cast_params ( relation , value , sort , drop )
1287+ value = cast_params ( relation . cardinality , value , sort , drop )
12881288
12891289 case Relation . cast ( relation , data , value , current , on_cast ) do
12901290 { :ok , change , relation_valid? } when change != original ->
12911291 valid? = changeset . valid? and relation_valid?
12921292 changes = Map . put ( changes , key , change )
12931293 changeset = % { force_update ( changeset , opts ) | changes: changes , valid?: valid? }
1294- missing_relation ( changeset , key , current , required? , relation , opts )
1294+ missing_relation ( changeset , key , required? , relation , opts )
12951295
12961296 { :error , { message , meta } } ->
12971297 meta = [ validation: type ] ++ meta
@@ -1300,23 +1300,22 @@ defmodule Ecto.Changeset do
13001300
13011301 # ignore or ok with change == original
13021302 _ ->
1303- missing_relation ( changeset , key , current , required? , relation , opts )
1303+ missing_relation ( changeset , key , required? , relation , opts )
13041304 end
13051305 else
1306- missing_relation ( changeset , key , Map . get ( data , key ) , required? , relation , opts )
1306+ missing_relation ( changeset , key , required? , relation , opts )
13071307 end
13081308
13091309 update_in ( changeset . types [ key ] , fn { type , relation } ->
13101310 { type , % { relation | on_cast: on_cast } }
13111311 end )
13121312 end
13131313
1314- defp cast_params ( % { cardinality: :many } = relation , nil , sort , drop )
1315- when is_list ( sort ) or is_list ( drop ) do
1316- cast_params ( relation , % { } , sort , drop )
1314+ defp cast_params ( :many , nil , sort , drop ) when is_list ( sort ) or is_list ( drop ) do
1315+ cast_params ( :many , % { } , sort , drop )
13171316 end
13181317
1319- defp cast_params ( % { cardinality: : many} , value , sort , drop ) when is_map ( value ) do
1318+ defp cast_params ( : many, value , sort , drop ) when is_map ( value ) do
13201319 drop = if is_list ( drop ) , do: drop , else: [ ]
13211320
13221321 { sorted , pending } =
@@ -1334,7 +1333,7 @@ defmodule Ecto.Changeset do
13341333 |> Enum . map ( & elem ( & 1 , 1 ) ) )
13351334 end
13361335
1337- defp cast_params ( % { cardinality: : one} , value , sort , drop ) do
1336+ defp cast_params ( : one, value , sort , drop ) do
13381337 if sort do
13391338 raise ArgumentError , ":sort_param not supported for belongs_to/has_one"
13401339 end
@@ -1346,7 +1345,7 @@ defmodule Ecto.Changeset do
13461345 value
13471346 end
13481347
1349- defp cast_params ( _relation , value , _sort , _drop ) do
1348+ defp cast_params ( _cardinality , value , _sort , _drop ) do
13501349 value
13511350 end
13521351
@@ -1367,38 +1366,9 @@ defmodule Ecto.Changeset do
13671366
13681367 defp key_as_int ( key_val ) , do: key_val
13691368
1370- defp on_cast_default ( type , module ) do
1371- fn struct , params ->
1372- try do
1373- module . changeset ( struct , params )
1374- rescue
1375- e in UndefinedFunctionError ->
1376- case __STACKTRACE__ do
1377- [ { ^ module , :changeset , args_or_arity , _ } ]
1378- when args_or_arity == 2
1379- when length ( args_or_arity ) == 2 ->
1380- raise ArgumentError , """
1381- the module #{ inspect ( module ) } does not define a changeset/2 function,
1382- which is used by cast_#{ type } /3. You need to either:
1383-
1384- 1. implement the #{ type } .changeset/2 function
1385- 2. pass the :with option to cast_#{ type } /3 with an anonymous
1386- function of arity 2 (or possibly arity 3, if using has_many or
1387- embeds_many)
1388-
1389- When using an inline embed, the :with option must be given
1390- """
1391-
1392- stacktrace ->
1393- reraise e , stacktrace
1394- end
1395- end
1396- end
1397- end
1398-
1399- defp missing_relation ( changeset , name , current , required? , relation , opts ) do
1400- % { changes: changes , errors: errors } = changeset
1401- current_changes = Map . get ( changes , name , current )
1369+ defp missing_relation ( changeset , name , required? , relation , opts ) do
1370+ % { data: data , changes: changes , errors: errors } = changeset
1371+ current_changes = Map . get_lazy ( changes , name , fn -> Map . get ( data , name ) end )
14021372
14031373 if required? and Relation . empty? ( relation , current_changes ) do
14041374 errors = [
0 commit comments