Phoenix使用连接和预加载数据渲染json

时间:2016-11-28 16:47:24

标签: elixir phoenix-framework

我想渲染json,其中包含与foreign_key相关的两个模型(Event和Activity)。

在控制器中,我执行此查询:

def all_nested(conn, %{"event_id" => id}) do
  event = Repo.get! nested_all_query, id
  render(conn, "show_all.json", event: event)
end

defp nested_all_query do
  from event in Event,
    left_join: activities in assoc(event, :activities),
    preload: [activities: activities]
end

当我在iex控制台上尝试该查询时,查询返回正确的结果,并且里面有一个Activity的“活动”数组。

然后,在渲染时,我在视图上有这个代码:

def render("show_all.json", %{event: event}) do
  render_one(event, Project.EventView, "event_all.json")
end

def render("event.json", %{event: event}) do
  %{id: event.id,
    name: event.name,
    description: event.description,
    num_participants: event.num_participants,
    minimum_age: event.minimum_age,
    price: event.price,
    date_start: event.date_start,
    date_end: event.date_end,
    reg_date_open: event.reg_date_open,
    reg_date_close: event.reg_date_close,
    rules: event.rules}
end

def render("event_all.json", %{event: event}) do
   render("event.json", %{event: event})
   |> Map.put_new(:activities, render_many(event.activities, Project.ActivityView, "activity.json"))
end

我调用render_many来获取从ActivityView呈现动作获取json的活动(单独地,此动作可以正常工作)。

使用此代码,我有这个错误:

[error] #PID<0.575.0> running Project.Endpoint terminated
Server: localhost:4000 (http)
Request: GET /api/events/1/all
** (exit) an exception was raised:
    ** (Poison.EncodeError) unable to encode value: {nil, "activities"}
        (poison) lib/poison/encoder.ex:354: Poison.Encoder.Any.encode/2
        (poison) lib/poison/encoder.ex:213: anonymous fn/4 in Poison.Encoder.Map.encode/3
        (poison) lib/poison/encoder.ex:214: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3
        (poison) lib/poison/encoder.ex:214: Poison.Encoder.Map.encode/3
        (poison) lib/poison/encoder.ex:213: anonymous fn/4 in Poison.Encoder.Map.encode/3
        (poison) lib/poison/encoder.ex:214: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3
        (poison) lib/poison/encoder.ex:214: Poison.Encoder.Map.encode/3
        (poison) lib/poison/encoder.ex:232: anonymous fn/3 in Poison.Encoder.List.encode/3
        (poison) lib/poison/encoder.ex:233: Poison.Encoder.List."-encode/3-lists^foldr/2-1-"/3
        (poison) lib/poison/encoder.ex:233: Poison.Encoder.List.encode/3
        (poison) lib/poison/encoder.ex:213: anonymous fn/4 in Poison.Encoder.Map.encode/3
        (poison) lib/poison/encoder.ex:214: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3
        (poison) lib/poison/encoder.ex:214: Poison.Encoder.Map.encode/3
        (poison) lib/poison.ex:41: Poison.encode!/2
        (phoenix) lib/phoenix/controller.ex:642: Phoenix.Controller.do_render/4
        (project) web/controllers/event_controller.ex:1: Project.EventController.action/2
        (project) web/controllers/event_controller.ex:1: Project.EventController.phoenix_controller_pipeline/2
        (project) lib/project/endpoint.ex:1: Project.Endpoint.instrument/4
        (project) lib/phoenix/router.ex:261: Project.Router.dispatch/2
        (project) web/router.ex:1: Project.Router.do_call/2

我做错了什么?

祝你好运

1 个答案:

答案 0 :(得分:5)

解决了添加为::render tomany的活动:

def render("event_all.json", %{event: event}) do
     render("event.json", %{event: event})
     |> Map.put_new(:activities, render_many(event.activities, Project.ActivityView, "activity.json", as: :activity))
end