【问题标题】:protocol Enumerable not implemented for nil (phoenix-framework)没有为 nil 实现协议 Enumerable (phoenix-framework)
【发布时间】:2016-09-17 14:15:45
【问题描述】:

我在订单控制器中添加了“支付”功能,并为此添加了路由。

def payment(conn, %{"id" => id}) do
  foods = Repo.all(Food)
  order =
    Repo.get!(assoc(conn.assigns[:table], :orders), id)
    |> Repo.preload(order_items: :food)
  order_item_changeset =
    order
    |> build_assoc(:order_items)
    |> Pos1.OrderItem.changeset()
  order_changeset = Order.changeset(order)

  render(conn, "payment.html", order: order, order_item_changeset: order_item_changeset, order_changeset: order_changeset, foods: foods, payment: @payment)
end

resources "/tables", TableController do
  resources "/orders", OrderController do
    get "/payment", OrderController, :payment
end

我在表和订单下添加了付款路线,因为付款必须显示其表号和订单 ID。我在订单模板的 show.html 中添加了支付页面的链接。但是,它会导致 Protocol.UndefinedError。

[error] #PID<0.9096.0> running Pos1.Endpoint terminated
Server: localhost:4000 (http)
Request: GET /tables/1/orders/14
** (exit) an exception was raised:
    ** (Protocol.UndefinedError) protocol Enumerable not implemented for nil
        (elixir) lib/enum.ex:1: Enumerable.impl_for!/1
        (elixir) lib/enum.ex:116: Enumerable.reduce/3
        (elixir) lib/enum.ex:1486: Enum.reduce/3
        (pos1) Pos1.Router.Helpers.segments/3
        (pos1) web/router.ex:1: Pos1.Router.Helpers.table_order_order_path/5
        (pos1) web/templates/order/show.html.eex:59: Pos1.OrderView."show.html"/1
        (pos1) web/templates/layout/app.html.eex:41: Pos1.LayoutView."app.html"/1
        (phoenix) lib/phoenix/view.ex:344: Phoenix.View.render_to_iodata/3
        (phoenix) lib/phoenix/controller.ex:633: Phoenix.Controller.do_render/4
        (pos1) web/controllers/order_controller.ex:1: Pos1.OrderController.action/2
        (pos1) web/controllers/order_controller.ex:1: Pos1.OrderController.phoenix_controller_pipeline/2
        (pos1) lib/phoenix/router.ex:261: Pos1.Router.dispatch/2
        (pos1) web/router.ex:1: Pos1.Router.do_call/2
        (pos1) lib/pos1/endpoint.ex:1: Pos1.Endpoint.phoenix_pipeline/1
        (pos1) lib/plug/debugger.ex:93: Pos1.Endpoint."call (overridable 3)"/2
        (pos1) lib/phoenix/endpoint/render_errors.ex:34: Pos1.Endpoint.call/2
        (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
        (cowboy) src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

我该如何解决这个问题?我应该使用其他方法来定义功能支付吗?

这是来自 web/templates/order/show.html.eex:59 的代码

 <%= link "Confirm orders", to: table_order_order_path(@conn, :payment, @table, @order, @payment) %> 




<%= if @payment do %>
<%= link "Confirm orders", to: table_order_order_path(@conn, :payment, @table, @order, @payment) %>
<% end %>

【问题讨论】:

  • 您能否提供 web/templates/order/show.html.eex:59 的第 59 行以及您在调用 table_order_order_path 时使用的任何变量的值?

标签: elixir phoenix-framework


【解决方案1】:

错误protocol Enumerable not implemented for nil 表示您将nil 传递到应该使用列表或枚举的地方。

如果你向下看堆栈,你可以看到它是:Pos1.Router.Helpers.table_order_order_path/5 订单路径可能需要订单或订单 ID,即数据库中的 NULL。您可以简单地尝试在控制器中打印orderorder_item_changeset,看看哪个有问题。

如果你再看低一点,它会告诉你你的问题在于模板:web/templates/order/show.html.eex:59。在你的模板中试试这个:

<%= if @order do %> #or whichever value is nil
  your code here
<% end %>

【讨论】:

  • 谢谢,我已经在模板中尝试了上面的代码(order 和 order_changeset),但它说 order(order_changeset) 没有定义。我应该如何解决它?我从 web/templates/order/show.html.eex:59 .. 添加了代码
  • 呃,对不起。我忘记了@order 之前的@。这就是为什么它对你来说是未定义的。尝试在控制器中运行IO.inspect order 以查看您定义的哪些变量是nil。在知道哪些变量是nil之后,您应该修改模板。
  • 我添加了@payment 并且错误消息停止显示。但是,没有生成付款页面的链接...我做错了什么?
  • 您在render 中使用的控制器@payment。这是模块变量的语法。如果您的模块中没有定义@payment,则默认为nil
  • 非常感谢!我只是通过添加付款表单的值来修复它。
猜你喜欢
  • 2017-07-01
  • 2016-09-29
  • 2017-11-26
  • 2018-02-11
  • 2017-04-19
  • 2015-09-03
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
相关资源
最近更新 更多