2017-04-22 3 views
0

zu kodieren:Ecto Join-Abfrage verursacht (Poison.EncodeError) nicht in der Lage Wert

  1. Kategorien
  2. Unterkategorien
  3. categorySubcategories

1 Kategorie hat 0 zu viele Unterkategorien.

Ich habe diese Funktion, die alle Einträge aus Kategorien Tisch bekommt und bekommt nur die Einträge der Kategorie Tabelle, die zu der Kategorie gehören, die eine ID von 1:

def getCategories(conn) do 
    categories = all Api.Category 
    groceryItemSubcategories = from s in Api.Subcategory, 
    join: cs in Api.CategorySubcategory, on: cs.c_id == 1, 
    select: %{name: s.name, foo: cs.c_id} 
    conn 
    |> put_resp_content_type("application/json") 
    |> send_resp(200, Poison.encode!(%{categories: categories, groceryItemSubcategories: groceryItemSubcategories})) 
    end 

diesen Fehler geben:

23:10:27.169 [error] #PID<0.339.0> running Api.Router terminated 
Server: localhost:4000 (http) 
Request: GET /categories 
** (exit) an exception was raised: 
    ** (Poison.EncodeError) unable to encode value: {"subcategories", Api.Subcategory} 
     (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.ex:41: Poison.encode!/2 

Die endgültige Antwort lautet:

def getCategories(conn) do 
    categories = all Api.Category 
    groceryItemSubcategories = Api.Repo.all(from s in Api.Subcategory, 
    join: cs in Api.CategorySubcategory, on: cs.s_id == s.id, 
    join: c in Api.Category, on: c.id == cs.c_id, 
    where: c.id == 1, 
    select: %{name: s.name, foo: cs.c_id} 
    ) 
    conn 
    |> put_resp_content_type("application/json") 
    |> send_resp(200, Poison.encode!(%{categories: categories, groceryItemSubcategories: groceryItemSubcategories})) 
    end 

Der Teil, t macht Der Fehler verschwindet, umschließt die Anweisung in Api.Repo.All(). Dogbert war wirklich derjenige, der das beantwortet hat, also möchte ich das nicht beantworten.

+0

Gift kann nicht Tupeln kodieren. Versuchen Sie, eine Karte auszuwählen, z. 'select: {s.name, cs.c_id}' -> 'select:% {Name: s.name, foo: cs.c_id}'. – Dogbert

+0

@Dogbert Danke. Habe gerade den Fehler gepostet, den ich bekomme, wenn ich das tue. – BeniaminoBaggins

+0

Das ist ein Syntaxfehler. Könnten Sie den gesamten Code posten, den Sie ausprobiert haben? Wahrscheinlich fehlt irgendwo ein Komma oder etwas. – Dogbert

Antwort

1

Es gibt zwei Hauptprobleme mit dem ursprünglichen Code:

  1. Sie haben vergessen Repo.all in der zweiten Abfrage zu nennen.

  2. Sie wählen ein Tupel in der Abfrage aus und kodieren es dann in JSON. Poison behandelt die Codierung von Tupeln zu JSON. Sie können stattdessen eine Liste oder eine Karte auswählen, je nachdem, welche Datenstruktur Sie verwenden möchten. Hier ist, wie eine Karte wählen:

    groceryItemSubcategories = Api.Repo.all(from s in Api.Subcategory, 
        join: cs in Api.CategorySubcategory, on: cs.s_id == s.id, 
        join: c in Api.Category, on: c.id == cs.c_id, 
        where: c.id == 1, 
        select: %{name: s.name, c_id: cs.c_id})