I don't understand how I can change the values of a given changeset.
mix phoenix.new shop
cd shop
mix ecto.create
mix phoenix.gen.html Product products name price:integer
mix ecto.migrate
web/router.ex
[...]
scope "/", Shop do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
resources "/products", ProductController
end
[...]
I start the IEX and create a new changeset:
iex -S mix phoenix.server
iex(1)> alias Shop.Product
iex(2)> changeset = Product.changeset(%Product{price: 1})
#Ecto.Changeset<action: nil, changes: %{},
errors: [name: {"can't be blank", [validation: :required]}],
data: #Shop.Product<>, valid?: false>
How can I change that given changeset now? The following code doesn't work:
iex(3)> changeset = Product.changeset(changeset, %{name: "Orange"})
#Ecto.Changeset<action: nil, changes: %{name: "Orange"},
errors: [name: {"can't be blank", [validation: :required]}],
data: #Shop.Product<>, valid?: false>
Because of the errors I can't do a Shop.Repo.insert(changeset)
now.
I know that in this specific example I could change the iex(2) line to get the changeset I want. But I'd like to know how to manipulate a changeset after it's been created.
Product.changeset(changeset.data, Map.merge(changeset.changes, %{name: "Orange"}))
does the trick. Thanks to Dogbert.
$ iex -S mix phoenix.server
iex(1)> alias Shop.Product
Shop.Product
iex(2)> changeset = Product.changeset(%Product{price: 1})
#Ecto.Changeset<action: nil, changes: %{},
errors: [name: {"can't be blank", [validation: :required]}],
data: #Shop.Product<>, valid?: false>
iex(3)> changeset = Product.changeset(changeset.data, Map.merge(changeset.changes, %{name: "Orange"}))
#Ecto.Changeset<action: nil, changes: %{name: "Orange"}, errors: [],
data: #Shop.Product<>, valid?: true>
iex(4)>