8
votes

I'm using Elixir + Phoenix 1.3 and have defined an Accounts context. I wanted to use the accounts.ex file as an index to require in other modules to prevent it from becoming too big but I'm having trouble importing the functions from the other modules I created.

The structure of my files is as follows:

lib
|- Project
  |- Accounts
    |- accounts.ex
    |- user_api.ex

This is how my accounts.ex file looks:

# accounts.ex

defmodule Project.Accounts do
  @moduledoc """
  The Accounts context.
  """
  import Ev2Web
  import Ecto.Query, warn: false
  alias Project.{Accounts}

  use Accounts.UserAPI


end

And this is the module that I'm trying to import:

# user_api.ex

defmodule Project.Accounts.UserAPI do

  alias Project.{Repo}
  alias Project.{Accounts.User}

  def list_users do
    Repo.all(User)
  end
end

I want to be able to import my Project.Accounts.UserAPI module so that I can reference Project.Accounts.list_users() in my controller but the modules aren't being imported. I get the error function Project.Accounts.UserAPI.__using__/1 is undefined or private.

My controller looks like this:

defmodule ProjectWeb.UserController do
  use ProjectWeb, :controller

  alias Project.Accounts

  def index(conn, _params) do
    users = Accounts.list_users()
    render(conn, "index.html", users: users)
  end
end

Does anyone know how to import all of the functions from one module into another so that they are available for use? Thanks in advance!

1
Try import instead of use?Dogbert
@Dogbert I tried that but my functions were still unaccessible from my controllersJack Carlisle

1 Answers

7
votes

You have to include the __using__ macro and put all the code that should be compiled into the using module in there. Like this:

defmodule Project.Accounts.UserAPI do

  defmacro __using__(_) do
    quote do
      alias Project.{Repo}
      alias Project.{Accounts.User}

      def list_users do
        Repo.all(User)
      end
    end
  end
end