@@ -2521,6 +2521,28 @@ defmodule Ecto.RepoTest do
25212521 assert_received { :update , % { changes: [ always: 12 ] } }
25222522 end
25232523
2524+ test "update enforces writable fields added by prepare_changes" do
2525+ % { always: 10 , never: nil } =
2526+ % MySchemaWritable { id: 1 }
2527+ |> Ecto.Changeset . change ( % { always: 10 } )
2528+ |> Ecto.Changeset . prepare_changes ( & Ecto.Changeset . put_change ( & 1 , :never , 11 ) )
2529+ |> TestRepo . update! ( )
2530+
2531+ assert_received { :update , % { changes: [ always: 10 ] } }
2532+
2533+ message = ~r"""
2534+ you are attempting to write to the field :never of #{ inspect ( __MODULE__ . MySchemaWritableRaise ) } but
2535+ the `:writable` option of this field indicates the field should not be written to during an update.
2536+ """
2537+
2538+ assert_raise ArgumentError , message , fn ->
2539+ % MySchemaWritableRaise { id: 2 }
2540+ |> Ecto.Changeset . change ( % { always: 12 } )
2541+ |> Ecto.Changeset . prepare_changes ( & Ecto.Changeset . put_change ( & 1 , :never , 13 ) )
2542+ |> TestRepo . update! ( )
2543+ end
2544+ end
2545+
25242546 test "update is a no-op when updatable fields are not changed" do
25252547 % MySchemaWritable { id: 1 }
25262548 |> Ecto.Changeset . change ( % { never: "can't update" , insert: "can't update either" } )
@@ -2654,6 +2676,29 @@ defmodule Ecto.RepoTest do
26542676 assert Enum . sort ( inserted_fields ) == [ always: 12 , id: 2 , insert: 11 ]
26552677 end
26562678
2679+ test "insert enforces writable fields added by prepare_changes" do
2680+ % { always: 10 , never: nil } =
2681+ % MySchemaWritable { id: 1 }
2682+ |> Ecto.Changeset . change ( % { always: 10 } )
2683+ |> Ecto.Changeset . prepare_changes ( & Ecto.Changeset . put_change ( & 1 , :never , 11 ) )
2684+ |> TestRepo . insert! ( )
2685+
2686+ assert_received { :insert , % { fields: inserted_fields } }
2687+ assert Enum . sort ( inserted_fields ) == [ always: 10 , id: 1 ]
2688+
2689+ message = ~r"""
2690+ you are attempting to write to the field :never of #{ inspect ( __MODULE__ . MySchemaWritableRaise ) } but
2691+ the `:writable` option of this field indicates the field should not be written to during an insert.
2692+ """
2693+
2694+ assert_raise ArgumentError , message , fn ->
2695+ % MySchemaWritableRaise { id: 2 }
2696+ |> Ecto.Changeset . change ( % { always: 12 } )
2697+ |> Ecto.Changeset . prepare_changes ( & Ecto.Changeset . put_change ( & 1 , :never , 13 ) )
2698+ |> TestRepo . insert! ( )
2699+ end
2700+ end
2701+
26572702 test "insert with returning" do
26582703 % MySchemaWritable { id: 1 }
26592704 |> Ecto.Changeset . change ( % { always: 10 , never: 11 , insert: 12 } )
0 commit comments