Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elixir List All Modules in Namespace

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?

like image 683
user2694306 Avatar asked Jan 19 '17 04:01

user2694306


1 Answers

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.

like image 188
Aleksei Matiushkin Avatar answered Oct 22 '22 03:10

Aleksei Matiushkin