Generators: Contexts and Schemas - p85
Here is the code I have:
catalog.ex
:
def markdown_product(%Product{} = product, unit_price) do
product
|> Product.changeset_price(unit_price)
|> Repo.update()
end
product.ex
:
def changeset_price(product, unit_price) do
product
|> cast(unit_price, [:unit_price])
|> validate_number(:unit_price, greater_than: 0.0)
end
My commands:
# mix priv/generators_cli_commands.exs
# or `iex -S mix`, then enter line-by-line
alias Pento.Catalog
random_sku = Enum.random(0 .. 1_000_000)
product_attrs = %{
name: "Chess",
description: "The classic strategy game",
unit_price: 10.0,
sku: random_sku,
}
{:ok, product} = Catalog.create_product(product_attrs)
unit_price = 3.0
Catalog.markdown_product(product, unit_price)
It runs OK until the last line, which gives:
** (Ecto.CastError) expected params to be a :map, got: `3.0`
There is some generated @spec
, but it doesn’t mean much to me right now:
@spec markdown_product(
%Pento.Catalog.Product{optional(atom) => any},
:invalid | %{optional(:__struct__) => none, optional(atom | binary) => any}
) :: any
A few questions:
- How can I tell that it expects a :map for
unit_price
?- Why does it expect a map?
- How can I tell Elixir that I expect this second paramter to be a float?
Thanks!