@@ -434,7 +434,7 @@ defmodule Ecto.Repo.Schema do
434434 struct = struct_from_changeset! ( :insert , changeset )
435435 schema = struct . __struct__
436436 dumper = schema . __schema__ ( :dump )
437- { insertable_fields , non_insertable } = schema . __schema__ ( :insertable )
437+ { keep_fields , drop_fields } = schema . __schema__ ( :insertable_fields )
438438 assocs = schema . __schema__ ( :associations )
439439 embeds = schema . __schema__ ( :embeds )
440440
@@ -452,8 +452,8 @@ defmodule Ecto.Repo.Schema do
452452 # On insert, we always merge the whole struct into the
453453 # changeset as changes, except the primary key if it is nil.
454454 changeset = put_repo_and_action ( changeset , :insert , repo , tuplet )
455- changeset = Relation . surface_changes ( changeset , struct , insertable_fields ++ assocs )
456- changeset = update_in ( changeset . changes , & drop_non_writable_changes! ( & 1 , non_insertable , :insert ) )
455+ changeset = Relation . surface_changes ( changeset , struct , keep_fields ++ assocs )
456+ changeset = update_in ( changeset . changes , & drop_non_writable_changes! ( & 1 , drop_fields , schema , :insert ) )
457457
458458 wrap_in_transaction ( adapter , adapter_meta , opts , changeset , assocs , embeds , prepare , fn ->
459459 assoc_opts = assoc_opts ( assocs , opts )
@@ -472,7 +472,7 @@ defmodule Ecto.Repo.Schema do
472472 { changes , cast_extra , dump_extra , return_types , return_sources } =
473473 autogenerate_id ( autogen_id , changes , return_types , return_sources , adapter )
474474
475- changes = Map . take ( changes , insertable_fields )
475+ changes = Map . take ( changes , keep_fields )
476476 autogen = autogenerate_changes ( schema , :insert , changes )
477477
478478 dump_changes =
@@ -544,7 +544,7 @@ defmodule Ecto.Repo.Schema do
544544 struct = struct_from_changeset! ( :update , changeset )
545545 schema = struct . __struct__
546546 dumper = schema . __schema__ ( :dump )
547- { updatable_fields , non_updatable } = schema . __schema__ ( :updatable )
547+ { keep_fields , drop_fields } = schema . __schema__ ( :updatable_fields )
548548 assocs = schema . __schema__ ( :associations )
549549 embeds = schema . __schema__ ( :embeds )
550550
@@ -561,7 +561,7 @@ defmodule Ecto.Repo.Schema do
561561 # fields into the changeset. All changes must be in the
562562 # changeset before hand.
563563 changeset = put_repo_and_action ( changeset , :update , repo , tuplet )
564- changeset = update_in ( changeset . changes , & drop_non_writable_changes! ( & 1 , non_updatable , :update ) )
564+ changeset = update_in ( changeset . changes , & drop_non_writable_changes! ( & 1 , drop_fields , schema , :update ) )
565565
566566 if changeset . changes != % { } or force? do
567567 wrap_in_transaction ( adapter , adapter_meta , opts , changeset , assocs , embeds , prepare , fn ->
@@ -576,7 +576,7 @@ defmodule Ecto.Repo.Schema do
576576 if changeset . valid? do
577577 embeds = Ecto.Embedded . prepare ( changeset , embeds , adapter , :update )
578578
579- changes = changeset . changes |> Map . merge ( embeds ) |> Map . take ( updatable_fields )
579+ changes = changeset . changes |> Map . merge ( embeds ) |> Map . take ( keep_fields )
580580 autogen = autogenerate_changes ( schema , :update , changes )
581581 dump_changes = dump_changes! ( :update , changes , autogen , schema , [ ] , dumper , adapter )
582582
@@ -625,20 +625,22 @@ defmodule Ecto.Repo.Schema do
625625 { :error , put_repo_and_action ( changeset , :update , repo , tuplet ) }
626626 end
627627
628- defp drop_non_writable_changes! ( changes , non_writable , action ) do
629- Enum . reduce ( non_writable , changes , fn { name , on_writable_violation } , changes ->
630- case Map . pop ( changes , name ) do
628+ defp drop_non_writable_changes! ( changes , non_writable_fields , schema , action ) do
629+ Enum . reduce ( non_writable_fields , changes , fn field , changes ->
630+ case Map . pop ( changes , field ) do
631631 { nil , changes } ->
632632 changes
633633 { _change , changes } ->
634- handle_writable_violation ( name , on_writable_violation , action )
634+ handle_writable_violation ( field , schema , action )
635635 changes
636636 end
637637 end )
638638 end
639639
640- defp handle_writable_violation ( name , on_writable_violation , action ) do
641- message = "attempted to write to non-writable field #{ inspect ( name ) } during #{ action } "
640+ defp handle_writable_violation ( field , schema , action ) do
641+ on_writable_violation = schema . __schema__ ( :on_writable_violation ) [ field ]
642+
643+ message = "attempted to write to non-writable field #{ inspect ( field ) } during #{ action } "
642644
643645 case on_writable_violation do
644646 :raise ->
@@ -990,7 +992,7 @@ defmodule Ecto.Repo.Schema do
990992 end
991993
992994 defp replace_all_fields! ( _kind , schema , to_remove ) do
993- { updatable_fields , _ } = schema . __schema__ ( :updatable )
995+ { updatable_fields , _ } = schema . __schema__ ( :updatable_fields )
994996 Enum . map ( updatable_fields -- to_remove , & field_source! ( schema , & 1 ) )
995997 end
996998
0 commit comments