Reputation: 4060
I am working on an Elixir/Phoenix app that is intended to create a user in my UserController
controller. There is a /lib/helpers/user_helpers
directory with a number of modules (each in a separate file). These modules all have a common namespace UserHelpers.ModuleName
. In each of these modules I have a function called apply
which I want to apply to the user data. For example if I have the following file structure:
-lib
-helpers
-user_helpers
-module1
-module2
-...
-moduleN-1
-moduleN
where each of module1
and module2
contains a function apply(user_info)
which returns user_info
. In my UserController
I have the function create(conn, params)
in which I want to run the following:
user_data
|> UserHelpers.Module1.create
|> UserHelpers.Module2.create
|> ...
|> UserHelpers.ModuleN-1.create
|> UserHelpers.ModuleN.create
But I'm unsure how to dynamically load all of the modules in the UserHelpers
folders to do the above. Any suggestions?
Upvotes: 10
Views: 6062
Reputation: 121010
Assuming, that your application is called :my_app
and helpers have the .ex
extension and/or explicitly compiled into your application:
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)
returns the list of modules, known to that application. The second line filters out those unneeded, and the latter one applies their :create
functions to user_data
subsequently.
You probably want to embed Enum.sort
just before the last line to sort the modules to apply in the appropriate order.
Upvotes: 21