我正在开发一个Elixir / Phoenix应用程序,用于在我的UserController
控制器中创建用户。有一个/lib/helpers/user_helpers
目录,其中包含许多模块(每个模块都在一个单独的文件中)。这些模块都有一个共同的命名空间UserHelpers.ModuleName
。在每个模块中,我都有一个名为apply
的函数,我想将其应用于用户数据。例如,如果我有以下文件结构:
-lib
-helpers
-user_helpers
-module1
-module2
-...
-moduleN-1
-moduleN
module1
和module2
中的每一个都包含一个返回apply(user_info)
的函数user_info
。在我的UserController
中,我有一个函数create(conn, params)
,我想在其中运行以下内容:
user_data
|> UserHelpers.Module1.create
|> UserHelpers.Module2.create
|> ...
|> UserHelpers.ModuleN-1.create
|> UserHelpers.ModuleN.create
但我不确定如何动态加载UserHelpers
文件夹中的所有模块来执行上述操作。有什么建议吗?
答案 0 :(得分:7)
假设您的应用程序被称为:my_app
并且帮助者具有.ex
扩展名和/或显式编译到您的应用程序中:
with {:ok, list} <- :application.get_key(:my_app, :modules) do
list
|> Enum.filter(& &1 |> Module.split |> Enum.take(1) == ~w|UserHelpers|)
|> Enum.reduce(user_data, fn m, acc -> apply(m, :create, acc) end)
end
:application.get_key(:my_app, :modules)
返回该应用程序已知的模块列表。第二行过滤掉那些不需要的内容,后一行将:create
函数随后应用到user_data
。
您可能希望在最后一行之前嵌入Enum.sort
,以便按照适当的顺序对要应用的模块进行排序。