我有这段代码:
if Map.has_key?(dbShop, "id") && Map.has_key?(dbProduct, "id") do
case Api.Repo.insertProductShop(conn, dbShop.id, dbProduct.id) do
{:ok, productShop} ->
{:ok, productShop}
{:error, changeset} ->
Tuple.append(errors, "could not insert product in the Shop")
end
else
IO.puts("(dbShop, id) && Map.has_key?(dbProduct, id) failed")
IO.inspect(dbShop)
IO.inspect(dbProduct)
end
代码执行使其成为else
子句并将其记录到控制台:
(dbShop, id) && Map.has_key?(dbProduct, id) failed
%Api.Shop{__meta__: #Ecto.Schema.Metadata<:loaded, "shops">, id: 23,
latitude: -36.846691, longitude: 174.7745803, name: "Yard Bar & Eatery",
placeId: "ChIJp6DGbAdIDW0RcbnExyPHvCk"}
%Api.Product{__meta__: #Ecto.Schema.Metadata<:loaded, "products">,
brand: "baba", description: " zhzngshshhshs", id: 34, image: "no-image",
name: "Nsn", numberOfVotes: nil, rating: nil}
因此我们可以看到dbShop
和dbProduct
都有一个id
,并且代码执行在某种程度上永远不会进入if
子句。我的if
条款我做错了什么?我想检查它们是否都有id
,如果是,请进入if
子句。
路由器中的全部功能:
post "/products" do
errors = {}
postedProduct = conn.body_params
dbProduct = %{}
dbShop = %{}
case Api.Repo.insertProduct(conn, postedProduct) do
{:success, product} ->
dbProduct = product
case Api.Repo.insertProductCategories(conn, postedProduct, dbProduct.id) do
{:ok, categories} ->
{:ok, categories}
{:error, failed_operation, failed_value, changes_so_far} ->
Tuple.append(errors, "could not insert productCategories. Product already has that category")
end
{:error, changeset} ->
IO.puts("product not inserted")
Tuple.append(errors, "could not insert product. Product already existed")
IO.inspect(errors)
end
if Map.has_key?(postedProduct, "shop") do
case Api.Repo.insertShop(conn, postedProduct["shop"]) do
{:ok, shop} ->
dbShop = shop
if Map.has_key?(dbShop, :id) && Map.has_key?(dbProduct, :id) do
case Api.Repo.insertProductShop(conn, dbShop.id, dbProduct.id) do
{:ok, productShop} ->
{:ok, productShop}
{:error, changeset} ->
Tuple.append(errors, "could not insert product in the Shop")
end
else
IO.puts("(dbShop, id) && Map.has_key?(dbProduct, id) failed")
IO.inspect(dbShop)
IO.inspect(dbProduct)
end
{:error, changeset} -> # shop already exists
# Tuple.append(errors, "could not insert shop")
if Map.has_key?(dbShop, "id") && Map.has_key?(dbProduct, "id") do
case Api.Repo.insertProductShop(conn, dbShop.id, dbProduct.id) do
{:ok, productShop} ->
{:ok, productShop}
{:error, changeset} ->
Tuple.append(errors, "The product has already been added to the shop")
end
end
end
end
if tuple_size(errors) > 0 do
IO.puts("errors")
IO.inspect(errors)
conn
|> put_resp_content_type("application/json")
|> send_resp(200, Poison.encode!(%{
successs: "success",
errors: errors
}))
else
conn
|> put_resp_content_type("application/json")
|> send_resp(200, Poison.encode!(%{
successs: "success"
}))
end
end
答案 0 :(得分:1)
您的地图有一个原子:id
作为键,而不是字符串"id"
,因此您的if
应为:
if Map.has_key?(dbShop, :id) && Map.has_key?(dbProduct, :id) do
如果该值保证为非零(如果存在),您还可以将其缩短为:
if dbShop[:id] && dbProduct[:id] do
如果密钥不存在,则使用括号语法访问值不会引发错误,而是返回nil
,这是Elixir中的虚假值。
答案 1 :(得分:1)
在Elixir中使用if
是一种代码气味,并暗示代码可能以更明确的方式重写。在这里,我将使用Kernel.SpecialForms.with/1
,而不是:
if Map.has_key?(dbShop, :id) && Map.has_key?(dbProduct, :id) do
# true
else
# false
end
使用:
with %{id: shopId} when not is_nil(shopId) <- dbShop,
%{id: prodId} when not is_nil(prodId) <- dbProduct do
# true
else
^dbProduct -> IO.puts "prodId is nil"
^dbShop -> IO.puts "shopId is nil"
end