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]