Elixir地图改变结构传递

时间:2016-04-27 10:14:28

标签: elixir phoenix-framework

我错过了我的凤凰代码基本的东西

这是我的控制器

JFileChooser

在我看来

  def show(conn, %{"id" => id}) do
    user = Repo.get!(User, id)

    query =
        from c in Card,
            where: c.user_id == 1,
            select: {c.id, c.inserted_at, c.estimate_name, c.product}
    estimates = Repo.all(query)

    render(conn, "show.json", %{user: user, estimates: estimates})
    # render(conn, "show.json", user: user)
  end

但是我收到了错误,这似乎是因为我的数据已从 # def render("show.json", %{user: user}) do def render("show.json", %{user: user, estimates: estimates}) do %{data: render_one(%{user: user, estimates: estimates}, Api.UserView, "user.json") } # %{data: render_one(user, Api.UserView, "user.json")} # ** New code since original post ** # %{data: render("user.json", %{user: user, estimates: estimates})} end def render("user.json", %{user: user, estimates: estimates}) do # def render("user.json", %{user: user}) do %{id: user.id, firstname: user.firstname, lastname: user.lastname, email: user.email, customerId: user.customerId, estimates: render("estimates.json", estimates)} # **Line with last error** end def render("estimates.json", [head | _estimates]) do # Enum.map(estimates, fn estimate -> render(mapper estimate, MosaicApi.UserView, "summaryEstimate.json") } end) # render(mapper(head), MosaicApi.UserView, "summaryEstimate.json") render("summaryEstimate.json", mapper(head)) end # ** I'm fear I have added unnecessary complexity here ** def mapper({id, date, name, product}) do %{id: id, creation_date: date, estimate_name: name, product: product} end def render("summaryEstimate.json", estimate) do %{id: estimate.id, estimate_name: estimate.estimate_name, product: estimate.product} end 变为%{user: ..., estimates: [...]}

这是怎么发生的,我怎么能阻止它?

%{user: %{estimates:[...], user: %{...}}

2 个答案:

答案 0 :(得分:3)

render_one/4render_many/4函数会从视图中选择分配名称。我在Render many to many relationship JSON in Phoenix Framework

中解释了这一点

所以当你打电话时会发生什么:

render_one(%{user: user, estimates: estimates}, Api.UserView, "user.json")

是否使用以下参数调用render

render("user.json", %{user: %{user: %{...}, estimates: [...]})

您可以使用as更改分配名称:

render_one(%{user: user, estimates: estimates}, Api.UserView, "user.json", as: :data)

将使用以下内容调用渲染:

render("user.json", %{data: %{user: %{...}, estimates: [...]})

您可以将其与:

匹配
def render("user.json", %{data: %{user: user, estimates: estimates}}) do

您可以直接致电render而不是使用render_one来避免这种情况:

render("user.json", %{user: user, estimates: estimates})

另一种选择是使用嵌套用户结构内部估计值的数据结构。也许是通过向模式添加虚拟属性。

修改

  def render("show.json", %{user: user, estimates: estimates}) do
    %{data: render("user.json", %{user: user, estimates: estimates})}
  end

  def render("user.json", %{user: user, estimates: estimates}) do
    %{id: user.id,
      ...
      estimates: render_many(estimates, __MODULE__, "estimates.json", estimates. as: estimate)}
  end

  def render("estimates.json", %{estimate: {id, _date, name, product}}) do
    %{id: id,
      estimate_name: name,
      product: product}
  end

答案 1 :(得分:3)

  

这是怎么发生的,我怎么能阻止它?

那是因为Phoenix.View.render_one将您的作品包裹在视图名称中的键中。

From its docs

  

以下内容:

render_one user, UserView, "show.html"
     

大致相当于:

if user != nil do
  render(UserView, "show.html", user: user)
end
     

基础用户将作为:user传递给视图和模板,该视图从视图名称中转换。

您应该直接致电render/2

def render("show.json", %{user: user, estimates: estimates}) do
  %{data: render("user.json", %{user: user, estimates: estimates}}
end