2017-04-16 2 views
0

Si je cours Api.Category |> Api.Repo.all dans iex je reçois cette réponse dans le terminal (au fond, je reçois deux lignes de la table de base de données « catégories »):erreur en essayant de récupérer la base de données et renvoyer le résultat en réponse 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"}] 

J'essaie de renvoyer cette réponse dans une réponse http, mais j'obtiens cette erreur (je pense qu'elle ne récupère rien de la base de données).

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 

Voici ma fonction qui tente d'obtenir les entrées dans le tableau de base de données « catégories » et les retourner dans une réponse 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 

Qu'est-ce que je fais mal?

Je mis en place les connexions:

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 a toutes mes requêtes de base de données (y compris getCategories qui devrait être dans un contrôleur) qui m'a dit est bizarre mais bon, l'itération 1, je veux juste d'abord faire fonctionner:

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 

partie pertinente de router.ex

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

Je passe en revue localhost:4000/categories et obtiens l'erreur en haut.

sortie de IO.puts (catégories) - il a beaucoup de lignes dupliquées, mais c'est un autre problème lol.

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

S'il vous plaît montrer votre fonction 'index' dans le contrôleur de categories'. Le problème n'est probablement pas dans 'getCategories'. – mudasobwa

+0

@mudasobwa Je pense que je viens d'ajouter ce que vous demandez - mon projet a une structure bizarre, donc je n'ai pas encore de contrôleur. Faites-moi savoir s'il me manque quelque chose. Bravo – BeniaminoBaggins

+0

Mind pour mettre 'IO.inspect (categories)' juste après 'categories = all Api.Category' et vérifier ce qui sera produit? – mudasobwa

Répondre

1

Vous devez faire une mise en œuvre personnalisée de Poison.Encoder pour votre struct afin qu'il ne cherche pas à coder le champ __meta__ de la struct (qui contient un tuple en ce qui Poison ne gère pas). La meilleure façon de le faire est d'ajouter un @derive au struct avec les noms des champs que vous souhaitez encoder:

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

Merci! Travaillé immédiatement après cela. – BeniaminoBaggins