【问题标题】:Phoenix Elixir: is making a POST using fetch to an action and returning JSON from template view so hard?Phoenix Elixir:使用 fetch 到操作并从模板视图返回 JSON 来制作 POST 这么难吗?
【发布时间】:2017-04-17 21:31:37
【问题描述】:

我确实有这个控制器和模板视图,当发布到创建操作时我收到了这个错误:

我是否错过了特别设置一些插件?

** (RuntimeError) expected action/2 to return a Plug.Conn, all plugs must receive a connection (conn) and return a connection

灵药 1.3.2 凤凰 1.2.1 毒药3.0

控制器中的部分代码

  def create(conn, %{"cart" => cart, "form" => form}) do

  ...

    if changeset_order.valid? do
      Repo.transaction fn ->
        # Save Order
        order = changeset_order 
                |> Repo.insert! 
                |> Repo.preload(:buyer)
        # Save Order Products
        Enum.map(order_products, fn order_product ->
          order_product = Repo.insert!(order_product) |> Repo.preload(:order)
          changeset = Ecto.Changeset.change(order_product) |> Ecto.Changeset.put_assoc(:order, order)
          Repo.update!(changeset)
        end)
        CheckoutService.charge_customer(total_amount, "fake-valid-nonce")
        render conn, "show.json", order: order <--- Is this failing due to is called from within a transaction ?
      end
    else
      render conn, ExRushlookApi.ChangesetView, "error.json", changeset: changeset_order
    end

模板视图

defmodule ExRushlookApi.OrderView do
  use ExRushlookApi.Web, :view

  def render("index.json", %{orders: orders}) do
    %{data: render_many(orders, __MODULE__, "order.json")}
  end

  def render("show.json", %{order: order}) do
    %{data: render_one(order, __MODULE__, "order.json")}
  end

  def render("order.json", %{order: order}) do
    order |> IO.inspect
    %{id: Map.get(order, :id)}
  end

  def render("errors.json", %{errors: errors}) do
    %{errors: render_many(errors, __MODULE__, "error.json")}
  end

  def render("error.json", %{error: error}) do
    %{
      key: error.key,
      value: error.value
    }
  end

end

更新:它是这样工作的。

if changeset_order.valid? do
      {:ok, order } = Repo.transaction fn ->
        # Save Order
        order = changeset_order 
                |> Repo.insert! 
                |> Repo.preload(:buyer)
        # Save Order Products
        Enum.map(order_products, fn order_product ->
          order_product = Repo.insert!(order_product) |> Repo.preload(:order)
          changeset = Ecto.Changeset.change(order_product) |> Ecto.Changeset.put_assoc(:order, order)
          Repo.update!(changeset)
        end)

        CheckoutService.charge_customer(total_amount, "fake-valid-nonce")
        order
      end
      conn
      |> render("show.json", order: order)
    else
      conn
      |> render(ExRushlookApi.ChangesetView, "error.json", changeset: changeset_order)
    end

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    您的事务块中有render conn, "show.json", ... 调用。它应该在块之后。事务块返回事务的结果,而不是最后的语句。

    如果你只想在成功时渲染show,你应该检查事务的结果并在那里处理它。

    【讨论】:

    • 是的,先生!你是对的。终于干活了。我的错。我更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    相关资源
    最近更新 更多