Ecto and enums for fields

Sometimes I want a DB table column only to contain a specific list of strings.

For example, I have a Resource schema, which has a :type field. This field must only contain a value among: “room”, “tool”, “human”, “other”.

I could create a new table ResourceType, but I think I’d rather hardcode the value in the resources table.

I came across a similar situation with a quiz I’ve built. I made a function in the Quiz context such as:

  def list_question_types do
    [
      "multiple_choice",
      "fill_in_the_blanks",
      "short_answer"
    ]
  end 

This allows the controller to give to the view the values required for the <select> input, which a user uses to specify which type of question he creates. The select will use each of these values for its options’ value attribute, and each of these values is mapped to a string in a gettext .pot file in order to show the text of the option in the user’s language:

# en
msgid "fill_in_the_blanks"
msgstr "Fill in the blanks"
# fr
msgid "fill_in_the_blanks"
msgstr "Remplir les blancs"

This is a simple solution and works fine. As this comes up in every project, I’d like to know if anyone thinks about another solution.

It is of course important that the view can get the list of values to populate a <select> input.

PostgreSQL enums work just fine for such scenarios. Have you tried using one for your problem?

2 Likes

An alternative is to use ecto_enum.

2 Likes