2017-05-26 38 views
0

我有这样的代码:灵药“如果”和“和”不按预期工作

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} 

所以我们可以看到dbShopdbProduct都有一个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 
+1

你的键是原子。试试'Map.has_key?(...,:id)'。 – Dogbert

+0

另外,你想用这个表达做什么?如果这两个值始终是商店和产品结构,即使“:id”的值为零或错误,它们也将始终“拥有”关键字“:id”。 – Dogbert

+0

@Dogbert谢谢!我想因为它没有':'在'id'前面,所以它不是原子。关于你的第二条评论,如果产品被插入到数据库中,dbProduct只会被填充。如果没有填充,它很可能已经在数据库中(唯一约束)。 – BeniaminoBaggins

回答

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

在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