2017-04-16 41 views
0

返回結果。如果我在iex運行Api.Category |> Api.Repo.all我得到的終端(基本上我從「類別」的數據庫表中的兩行)這樣的響應:錯誤試圖從數據庫中獲取並在HTTP響應

iex(1)> Api.Category |> Api.Repo.all 

16:21:55.775 [debug] QUERY OK source="categories" db=5.2ms decode=6.3ms 
SELECT c0."id", c0."name" FROM "categories" AS c0 [] 
[%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 1, 
    name: "Grocery Products"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 2, 
    name: "Meals"}] 

我試圖在http響應中發回該響應,但得到這個錯誤(我認爲它只是沒有從數據庫中檢索任何東西)。

Poison.EncodeError at GET /categories unable to encode value: {nil, "categories"} lib/poison/encoder.ex 
378 def encode(%{__struct__: _} = struct, options) do 
379 Poison.Encoder.Map.encode(Map.from_struct(struct), options) 
380 end 
381 
382 def encode(value, _options) do 
383 raise Poison.EncodeError, value: value 
384 end 
385end 

這裏是我的功能,試圖獲得在「類別」數據庫表中的條目,並在HTTP響應返回他們:

def getCategories(conn) do 
    categories = Api.Category |> Api.Repo.all 
    conn 
    |> put_resp_content_type("application/json") 
    |> send_resp(200, Poison.encode!(%{categories: categories})) 
    end 

我在做什麼錯?

我建立的連接:

application.ex:

defmodule Api.Application do 
    use Application 
    def start(_type, _args) do 
    import Supervisor.Spec, warn: false 
    children = [ 
     worker(__MODULE__, [], function: :run), 
     supervisor(Api.Repo, []), 
    ] 
    opts = [strategy: :one_for_one, name: Api.Supervisor] 
    Supervisor.start_link(children, opts) 
    end 
    def run do 
    { :ok, _ } = Plug.Adapters.Cowboy.http Api.Router, [] 
    end 
end 

repo.ex具有我一直在告訴我所有的數據庫查詢(包括getCategories這應該是在控制器)是怪異但是,嘿,迭代1,我只想得到它的第一份工作:

defmodule Api.Repo do 
    use Ecto.Repo, otp_app: :api 
    require Ecto.Query 
    import Plug.Conn 

    def insertCategories do 
    categories = [ 
     %Api.Category{name: "Grocery Products"}, 
     %Api.Category{name: "Meals"} 
    ] 
    Enum.each(categories, fn (category) -> insert(category) end) 
    end 

    def insertSubcategories do 
    subcategories = [ 
     %Api.Subcategory{name: "Meat"}, 
     %Api.Subcategory{name: "Dairy"}, 
     %Api.Subcategory{name: "Confectionary"}, 
     %Api.Subcategory{name: "Dessert"}, 
     %Api.Subcategory{name: "Baking"}, 
     %Api.Subcategory{name: "Condiments"}, 
     %Api.Subcategory{name: "Beverages"}, 
     %Api.Subcategory{name: "African"}, 
     %Api.Subcategory{name: "Argentine"}, 
     %Api.Subcategory{name: "Asian"}, 
     %Api.Subcategory{name: "Asian Fusion"}, 
     %Api.Subcategory{name: "BBQ"}, 
     %Api.Subcategory{name: "Bakery"}, 
     %Api.Subcategory{name: "Beverages"}, 
     %Api.Subcategory{name: "Brazilian"}, 
     %Api.Subcategory{name: "Breakfast"}, 
     %Api.Subcategory{name: "British"}, 
     %Api.Subcategory{name: "Cafe"}, 
     %Api.Subcategory{name: "Cambodian"}, 
     %Api.Subcategory{name: "Chinese"}, 
     %Api.Subcategory{name: "Coffee and Tea"}, 
     %Api.Subcategory{name: "Contemporary"}, 
     %Api.Subcategory{name: "Continental"}, 
     %Api.Subcategory{name: "Deli"}, 
     %Api.Subcategory{name: "Desserts"}, 
     %Api.Subcategory{name: "Drinks Only"}, 
     %Api.Subcategory{name: "European"}, 
     %Api.Subcategory{name: "Fijian"}, 
     %Api.Subcategory{name: "Filipino"}, 
     %Api.Subcategory{name: "Finger Food"}, 
     %Api.Subcategory{name: "Fish and Chips"}, 
     %Api.Subcategory{name: "French Fusion"}, 
     %Api.Subcategory{name: "German"}, 
     %Api.Subcategory{name: "Greek"}, 
     %Api.Subcategory{name: "Grill"}, 
     %Api.Subcategory{name: "Healthy Food"}, 
     %Api.Subcategory{name: "Ice Cream"}, 
     %Api.Subcategory{name: "Indian"}, 
     %Api.Subcategory{name: "Indonesian"}, 
     %Api.Subcategory{name: "International"}, 
     %Api.Subcategory{name: "Irish"}, 
     %Api.Subcategory{name: "Italian"}, 
     %Api.Subcategory{name: "Japanese"}, 
     %Api.Subcategory{name: "Jewish"}, 
     %Api.Subcategory{name: "Juices"}, 
     %Api.Subcategory{name: "Kiwi"}, 
     %Api.Subcategory{name: "Korean"}, 
     %Api.Subcategory{name: "Latin"}, 
     %Api.Subcategory{name: "American"}, 
     %Api.Subcategory{name: "Lebanese"}, 
     %Api.Subcategory{name: "Malaysian"}, 
     %Api.Subcategory{name: "Mediterranean"}, 
     %Api.Subcategory{name: "Mexican"}, 
     %Api.Subcategory{name: "Middle Eastern"}, 
     %Api.Subcategory{name: "Mongolian"}, 
     %Api.Subcategory{name: "Moroccan"}, 
     %Api.Subcategory{name: "Nepalese"}, 
     %Api.Subcategory{name: "North Indian"}, 
     %Api.Subcategory{name: "Pacific"}, 
     %Api.Subcategory{name: "Persian"}, 
     %Api.Subcategory{name: "Pizza"}, 
     %Api.Subcategory{name: "Portuguese"}, 
     %Api.Subcategory{name: "Pub Food"}, 
     %Api.Subcategory{name: "Seafood"}, 
     %Api.Subcategory{name: "Singaporean"}, 
     %Api.Subcategory{name: "South Indian"}, 
     %Api.Subcategory{name: "Spanish"}, 
     %Api.Subcategory{name: "Sri Lankan"}, 
     %Api.Subcategory{name: "Steakhouse"}, 
     %Api.Subcategory{name: "Street Food"}, 
     %Api.Subcategory{name: "Sushi"}, 
     %Api.Subcategory{name: "Taiwanese"}, 
     %Api.Subcategory{name: "Thai"}, 
     %Api.Subcategory{name: "Turkish"}, 
     %Api.Subcategory{name: "Vietnamese"}, 
    ] 
    Enum.each(subcategories, fn (subcategory) -> insert(subcategory) end) 
    end 

    def insertCategorySubcategories do 
    categorySubcategories = [ 
     %Api.CategorySubcategory{c_id: 1, s_id: 1}, 
     %Api.CategorySubcategory{c_id: 1, s_id: 2}, 
     %Api.CategorySubcategory{c_id: 1, s_id: 3}, 
     %Api.CategorySubcategory{c_id: 1, s_id: 4}, 
     %Api.CategorySubcategory{c_id: 1, s_id: 5}, 
     %Api.CategorySubcategory{c_id: 1, s_id: 6}, 
     %Api.CategorySubcategory{c_id: 1, s_id: 7}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 8}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 9}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 10}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 11}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 12}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 13}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 14}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 15}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 16}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 17}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 18}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 19}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 20}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 21}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 23}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 24}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 25}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 26}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 27}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 28}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 29}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 30}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 31}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 32}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 33}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 34}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 35}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 36}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 37}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 38}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 39}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 40}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 41}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 42}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 43}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 44}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 45}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 46}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 47}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 49}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 50}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 51}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 52}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 53}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 54}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 55}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 56}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 57}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 58}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 59}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 60}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 61}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 62}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 63}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 64}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 65}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 66}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 67}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 68}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 69}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 70}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 71}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 72}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 73}, 
     %Api.CategorySubcategory{c_id: 2, s_id: 74}, 
    ] 
    Enum.each(categorySubcategories, fn (categorySubcategory) -> insert(categorySubcategory) end) 
    end 

    def getCategories(conn) do 
    insertCategories 
    categories = all Api.Category 
    conn 
    |> put_resp_content_type("application/json") 
    |> send_resp(200, Poison.encode!(%{categories: categories})) 
    end 

    def getSubcategories do 
    Api.Subcategory |> all 
    end 
end 

的router.ex

相關部分
get "/categories/" do 
    [controller] = ["repo"] 
    Api.Repo.getCategories(conn) 
    end 

我瀏覽到localhost:4000/categories,並得到頂部的錯誤。

輸出IO.puts(類別) - 它有很多重複的行,但這是另一個問題哈哈。

16:59:54.922 [debug] QUERY OK source="categories" db=5.2ms decode=3.7ms 
SELECT c0."id", c0."name" FROM "categories" AS c0 [] 
[%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 1, 
    name: "Grocery Products"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 2, 
    name: "Meals"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 3, 
    name: "Grocery Products"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 4, 
    name: "Meals"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 5, 
    name: "Grocery Products"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 6, 
    name: "Meals"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 7, 
    name: "Grocery Products"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 8, 
    name: "Meals"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 9, 
    name: "Grocery Products"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 10, 
    name: "Meals"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 11, 
    name: "Grocery Products"}, 
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 12, 
    name: "Meals"}] 

16:59:55.038 [error] #PID<0.340.0> running Api.Router terminated 
Server: localhost:4000 (http) 
Request: GET /categories 
** (exit) an exception was raised: 
    ** (Poison.EncodeError) unable to encode value: {nil, "categories"} 
     (poison) lib/poison/encoder.ex:383: Poison.Encoder.Any.encode/2 
     (poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3 
     (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3 
     (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3 
     (poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3 
     (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3 
     (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3 
     (poison) lib/poison/encoder.ex:259: anonymous fn/3 in Poison.Encoder.List.encode/3 
+0

請出示在categories'控制你的'index'功能。這個問題可能不在'getCategories'中。 – mudasobwa

+0

@mudasobwa我想我剛剛添加了你所要求的 - 我的項目有一個奇怪的結構,所以我還沒有一個控制器。讓我知道如果我失去了一些東西。歡呼 – BeniaminoBaggins

+0

注意在'categories = all Api.Category'之後加上'IO.inspect(categories)',並檢查輸出結果是什麼? – mudasobwa

回答

1

你需要做的Poison.Encoder自定義實現對你的結構,以便它不會嘗試編碼結構的__meta__場(其中包含在其中的元組,其Poison不處理)。要做到這一點,最簡單的方法是將一個@derive添加到結構與要編碼字段的名稱:

defmodule Api.Category do 
    ... 
    @derive {Poison.Encoder, only: [:id, :name]} # <- add this 
    schema "categories" do 
    ... 
    end 
    ... 
end 
+0

謝謝!在那之後馬上工作。 – BeniaminoBaggins

相關問題