How to store reusable constants across different files

i have a gender field in ecto with this changeset criteria:

|> validate_inclusion(:gender, ["male", "female", "other", "prefer not to say"])

On the web end i am providing a dropdown for a user to select the Gender and hence want to repurpose these possible values for Gender on the web front.

What’s the best way to reuse constants in Elixir/Phoenix. I came across a solution specified as below (provided in 2016):

defmodule IbGib.Constants do

  @doc """
  Use this with `use IbGib.Constants, :ib_gib`
  """
  def ib_gib do
    quote do
      defp delim, do: "^"
      defp min_id_length, do: 1
      # etc...
    end
  end

  @doc """
  Use this with `use IbGib.Constants, :error_msgs`
  """
  def error_msgs do
    quote do
      defp emsg_invalid_relations do
        "Something about the rel8ns is invalid. :/"
      end
      # etc...
    end
  end

  @doc """
  When used, dispatch to the appropriate controller/view/etc.
  """
  defmacro __using__(which) when is_atom(which) do
    apply(__MODULE__, which, [])
  end
end

use IbGib.Constants, :ib_gib # < specifies only the ib_gib constants
use IbGib.Constants, :error_msgs

What kind of solution you have adopted?

Either with functions or like so: timex/constants.ex at main · bitwalker/timex · GitHub

2 Likes

What about changing the field type to Ecto Enum? Then you could use the values/2 function to get the values of the field in the UI. That’s how we do it in our product.

2 Likes

It worked really well; thanks for that @kevinschweikert

1 Like

Can’t you also use the values/2 function for the validate_inclusion rule? That way you should only have to define it once at the field level and reuse rather than keep repeating them.

1 Like

I don’t think you have to include the validation. Ecto Enum already does it for you.

1 Like