2017-05-26 59 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