RefData is a library for Phoenix projects that lets you provide reference data for your forms (e.g. Gender) without using a database table. It has been written as tool for POC development but can be used in PROD for fields that are common and do not form part of complex queries.
It's primary purpose is supporting the use of Phoenix.HTML.select.
The library is a supervised GenServer that starts as its own application when your
applications starts. It will hold all of your defined reference data in memory for fast
retrieval when needed.
Version 0.2.0 is a breaking change see CHANGELOG
The package can be installed by adding ref_data to your list of dependencies in
mix.exs:
def deps do
  [
    {:ref_data, "~> 0.2.1"}
  ]
endRefData defaults to looking for json objects at the root of the project in a
directory called ref_data. You can customise the path to your data by adding an entry
in your config.exs file. RefData expects one object per file.
use Mix.Config
...
config :ref_data,
  path: "path/to/your/dir"
...RefData supports a number of different definitions. The simplest definitons are a json object
that uses the type of reference data as the key and a list of values is generated as a list of key value pairs.
RefData will convert the definitions into Maps e.g.
/ref_data/gender.json
{ 
  "gender": [
    "Male", 
    "Female"
  ]
}Is converted into a map and held in state by the GenServer:
%{ 
  name: "gender", 
  data: [
    [key: "Male", value: "Male"], 
    [key: "Female", value: "Female"]
  ]
}RefData also supports more descriptive definitions so that you can assign your own key value pairs. E.g. if you
wish to support keys with different values you can provide the details:
/ref_data/active.json
{ 
  "name": "active", 
  "data": [
    {"key": "Enable", "value": "true"}, 
    {"key": "Disable", "value": "false"}
  ]
}This will be standardised as a map and stored in state:
%{ 
  name: "active", 
  data: [
    [key: "Enable", value: true], 
    [key: "Disable", value: false]
  ]
}You can also define grouped data by creating a list of key value pairs of data. This can be doen using
the simple json syntax:
/ref_data/countries.json
{
    "countries_grouped": 
    [
        { "Asia": ["Australia", "New Zealand"]},
        { "Americas": ["Canada", "USA"]}
    ]
}%{ 
  name: "countries_grouped", 
  data: [
    [ "Oceania": 
      [key: "Australia", value: "Australia"],
      [key: "New Zealand", value: "New Zealand"],
    ]
    [ "Amercias": 
      [key: "Canada", value: "Canada"],
      [key: "USA", value: "USA"],
    ]
  ]
}Alternatively, you can use the more detailed json definition to customise the values:
/ref_data/countries.json
{
    "name": "countries_grouped",
    "data": [
        { "Asia": [
            {"key":"Australia", "value": "Aussie"},
            {"key":"New Zealand", "value": "Kiwi"}]
        },
        { "Americas": [
            {"key":"Canada", "value": "Canuck"}, 
            {"key":"USA", "value": "Yank"}]
        }
    ]
}It will produce the standard map using your custom values
%{ 
  name: "countries_grouped", 
  data: [
    [ "Oceania": 
      [key: "Australia", value: "Aussie"],
      [key: "New Zealand", value: "Kiwi"],
    ]
    [ "Amercias": 
      [key: "Canada", value: "Canuck"],
      [key: "USA", value: "Yank"],
    ]
  ]
}Assuming you use RefData in a module named MyApp.MyRefData
defmodule MyApp.MyRefData do
  use RefData
endMy future plans include integrating GetText and CLDR and the configuration for these features will
be in this module. Below are some usage examples:
MyRefData.list_all_keys/0 will list all keys for data held in memory
iex(1)> MyRefData.list_all_keys
["months", "gender"]MyRefData.get/1 given a key it will return a list of data in the format required by Phoenix.HTML.select. If the
json defines grouped data it will return the appropriate format.
iex(1)> MyRefData.get("gender")
[
  [key: "Male", value: "Male"],
  [key: "Female", value: "Female"],
  [key: "Non-binary", value: "Non-binary"]
]iex(1)> MyRefData.get("countries")
[
  Asia: [
    [key: "Australia", value: "Australia"],
    [key: "New Zealand", value: "New Zealand"]
  ],
  Americas: [
    [key: "Canada", value: "Canada"], 
    [key: "USA", value: "Usa"]]
]MyRefData.get/2
When given a key and a switch you are able to disable data by passing in a list of values to disable.
iex(1)> MyRefData.get("gender", disabled: ["Female"])
[
  [key: "Male", value: "Male"],
  [key: "Female", value: "Female", disabled: true],
  [key: "Non-binary", value: "Non-binary"]
]