before_action:设置相当于在凤凰城
问题描述:
我想干涸此控制器:before_action:设置相当于在凤凰城
defmodule Xyz.ExampleController do
use Xyz, :controller
alias XyZ.Shops
def a(conn, %{"id" => id}) do
product = Shops.get_product!(id)
tax = product.price * 0.15
...
render(conn, "a.html", foobar: foobar, product: product)
end
def b(conn, %{"id" => id}) do
product = Shops.get_product!(id)
tax = product.price * 0.15
...
render(conn, "b.html", foobar: foobar, tax: tax)
end
def c(conn, %{"id" => id}) do
product = Shops.get_product!(id)
tax = product.price * 0.15
...
render(conn, "c.html", foobar: foobar)
end
end
每个函数这个部分开始:
product = Shops.get_product!(id)
tax = product.price * 0.15
在Ruby on Rails的世界,我想把它调用before_action :setup
来调用控制器。
在凤凰城实现这一目标的最佳方法是什么?
答
您可以尝试使用action/2
控制器方法。从controller docs:
由于控制器是插头,它们同时实现初始化/ 1和呼叫/ 2, 还提供/ 2命名作用的功能,该功能负责 调度插头堆叠之后的适当的动作(也可以覆盖 )。
在书中Programming Phoenix
克里斯·麦科德使用这个动作把一个通用参数所有控制器的功能是这样的:
def action(conn, _) do
apply(__MODULE__, action_name(conn), [conn, conn.params, conn.assigns.current_user])
end
所以像index/2
的每一个动作,现在是index/3
并具有当前用户为第三参数。
也许这可以帮助你?
+1
我不认为使用这种方法比插头更好,它不够灵活,并且在这种情况下不会给插件带来任何优势。 – JustMichael
你可以使用一个插件 - > https://hexdocs.pm/phoenix/plug.html,我求求你,不要把商业逻辑放到框架模块中。 – JustMichael
该逻辑不应位于控制器IMO中。如果是我,我会定义一个像这样工作的函数:'{product,tax} = Shops.get_product_and_tax!(id)'并且从每个动作调用它。 – Dogbert
比我会那样做。我认为将它放在一个插头中会更清洁。但我很高兴在每个操作中保留一行代码。 – wintermeyer