How to represent Keyword list in Ecto / Ecto.Schema

I would go for two maps handled by a homemade Ecto.Type:

  • key => value
  • key => index

When you want to access the key/value pairs in order, just use the second map.

Those two maps can also be wrapped in a single map, no need for two DB table columns either.

3 Likes

That is precisely what I started doing, apparently reinventing Enum.find_value/3 as @ruslandoga pointed out :slight_smile:

Custom type is possible and what you suggest is an option, which crossed my mind too. But still tried to ask first and find out whether someone knows a way out w/o any custom type(s).

1 Like

Keyword lists or just ordered key/value pairs are unknown to RDBMS engines as far as I am aware so even if you don’t code a custom Ecto.Type you’d still end up writing the same code anyway but someplace else.

So go for something that would be stored as JSON / JSONB in the DB in the form of %{v: keys_to_values, i: keys_to_indices} and have proper cast, dump and load functions and you’re golden. You might even open-source it in the form of an e.g. ecto_ordered_map library, if you feel generous. :smiley:

2 Likes

A very interesting solution.
Just curious: how about an embedded schema with fields :key, :value, :index and using embeds_many?
Then you put that into a map and order the list by the index and then you can further reduce it if needed, but you don’t lose searchability and filtering.
I feel I am missing something.

Don’t think I am following. Put what into a map, and what map? The OP asked about an ordered list of key/value pairs.