Elixir 在何处放置共享控制器代码
我有一个共享的控制器功能,我希望在控制器之间重用该功能:Elixir 在何处放置共享控制器代码,elixir,phoenix-framework,Elixir,Phoenix Framework,我有一个共享的控制器功能,我希望在控制器之间重用该功能: def render_unprocessable_entity(conn, changeset) do conn |> put_status(:unprocessable_entity) |> render(ExampleApp.ChangesetView, "error.json", changeset: changeset) end 问题:我可以把这个放在哪里?我试着把它放到control
def render_unprocessable_entity(conn, changeset) do
conn
|> put_status(:unprocessable_entity)
|> render(ExampleApp.ChangesetView, "error.json", changeset: changeset)
end
问题:我可以把这个放在哪里?我试着把它放到controllers/helpers/controller\u helper.ex中,它说:未定义函数put\u status/2
。我不能在这个助手中添加使用ExampleApp.Web,:controller
,因为它会与现有的controller冲突。我可以将它用作常规模块并使用alias,但这更多地是在任何地方键入ControllerHelper
我可以把它放到web.ex上也许?但也许我不应该把那个文件弄得太大
干涸代码的最佳方法是什么?用于从所需模块导入所有导出(公共)函数(在这种情况下是从帮助程序导入),而无需显式名称空间:
控制器\u helper.ex(或任何其他模块)
my_controller.ex(或任何其他模块)
无论您是否希望从单个模块访问所有使用它的人,您都可以覆盖回调以导入模块,即调用
use Helper
例如:
defmodule ExampleApp.ControllerHelper do
defmacro __using__(opts) do
quote do
defp render_unprocessable_entity(conn, changeset) do
conn
|> put_status(:unprocessable_entity)
|> render(ExampleApp.ChangesetView, "error.json", changeset: changeset)
end
end
end
end
这些功能(和)存在于当您使用Waveia.Web时导入的其他模块中:controller
你可以做:
def render_unprocessable_entity(conn, changeset) do
conn
|> Plug.Conn.put_status(:unprocessable_entity)
|> Phoenix.Controller.render(ExampleApp.ChangesetView, "error.json", changeset: changeset)
end
您可以在模块中定义它,然后在web.ex
中的控制器
函数中导入该模块,但是应该注意的是,无论何时将函数导入模块,都会隐藏模块的定义位置。这意味着在代码库中工作的其他人可能需要对代码进行一些挖掘,以找到函数的定义位置。相反,我建议您:
import MyModule, only: [render_unprocessable_entity: 2]
通过这种方式,查看控制器代码的人可以准确地看到“渲染”实体/2函数的来源。谢谢!成功了!奇怪的是,我必须明确指定
put_status
模块,这是一个隐藏在use Phoenix.Controller
中的细节。来自ruby,我想知道是否有一种方法可以编写代码,就好像代码可以复制到我的控制器中或从控制器中复制出来一样。对不起,我解释得不够清楚。但是我想在我的控制器中使用这个函数,但是把它放在一个单独的模块中,这样就可以在其他模块中导入/使用它。我在elixir中寻找类似ruby模块的东西,帮助器模块可以访问模块中包含的任何类中定义的所有现有函数。例如,有许多
或属性
方法也可以在这些模块中使用。如果您想从单个模块访问所有使用它的人,您可以覆盖回调以导入模块,即调用使用帮助器
。宾果!我想这正是我需要的。最后,我使用了defmodule ExampleApp.ControllerHelper do defmacro\uuuu使用(opts)do quote do defp render\u unprocessable\u entity(conn,changeset)do conn>put\u status(:unprocessable\u entity)|>render(ExampleApp.ChangesetView,“error.json”,changeset:changeset)结束
在我接受您的答案之前,您是否可以将此添加到您的答案中?@random或附加到答案中。
def render_unprocessable_entity(conn, changeset) do
conn
|> Plug.Conn.put_status(:unprocessable_entity)
|> Phoenix.Controller.render(ExampleApp.ChangesetView, "error.json", changeset: changeset)
end
import MyModule, only: [render_unprocessable_entity: 2]