Reputation: 12433
In this function, I need to check if the "price" variable is 0 or nil before I convert it into a float by doing priceFloat = price / 1
, or I get an arithmetic error.
def insert_product_shop(conn, product_id, shop_id, price) do
IO.inspect(price, label: "price")
priceFloat = price / 1
changeset = Api.ProductShop.changeset(%Api.ProductShop{p_id: product_id, s_id: shop_id, not_in_shop_count: 0, price: priceFloat})
errors = changeset.errors
valid = changeset.valid?
case insert(changeset) do
{:ok, product_shop} ->
{:ok, product_shop}
{:error, changeset} ->
{:error, :failure}
end
end
What is an idiomatic way to do so?
I tried this but I still get the arithmetic error:
def insert_product_shop(conn, product_id, shop_id, price) do
IO.inspect(price, label: "price")
case {price} do
{price} when price > 0 ->
priceFloat = price / 1
changeset = Api.ProductShop.changeset(%Api.ProductShop{p_id: product_id, s_id: shop_id, not_in_shop_count: 0, price: priceFloat})
errors = changeset.errors
valid = changeset.valid?
case insert(changeset) do
{:ok, product_shop} ->
{:ok, product_shop}
{:error, changeset} ->
{:error, :failure}
end
end
end
Upvotes: 1
Views: 4814
Reputation: 121000
The idiomatic way to do this would be to pattern match directly in function clauses:
def insert_product_shop(conn, product_id, shop_id, price)
when not is_number(price), do: {:error, :nil}
def insert_product_shop(conn, product_id, shop_id, price)
when price <= 0, do: {:error, :not_positive}
def insert_product_shop(conn, product_id, shop_id, price) do
priceFloat = price / 1
changeset =
Api.ProductShop.changeset(
%Api.ProductShop{p_id: product_id,
s_id: shop_id,
not_in_shop_count: 0,
price: priceFloat})
errors = changeset.errors
valid = changeset.valid?
case insert(changeset) do
{:ok, product_shop} ->
{:ok, product_shop}
{:error, changeset} ->
{:error, :failure}
end
end
First two clauses might be collapsed into one with a guard
when not is_number(price) or price <= 0
Upvotes: 3
Reputation: 222060
The reason your code doesn't work is because in Elixir, nil > 0
is true. You can do this instead:
if price not in [0, nil] do
...
else
...
end
or
if is_number(price) and price > 0 do
...
else
...
end
Upvotes: 6