How to insert a random key into a Map returned by an Ecto query?

Say I have this query:

query =
    from g in Group,
    where: g.team_id == ^user.team_id,
    where: g.slug == ^slug,
    preload: [:users]
group = Repo.one(query)

At the end there, what if I wanted to add a key called joined: true to that group variable? What would be the best way to about that?

Something I want to append certain keys to returned data from ecto queries.

Repo.one returns a struct, not a map. Assuming that the original Group struct does not have joined key, appending values with non-existent keys to a struct is not possible.

Two ways I can see this implemented is with Ecto virtual field or converting the value into a map (which doesn’t have the above restriction).

Using virtual field, you need to declare a field :joined, :boolean, virtual: true on your schema, and then you can use the update syntax %{ group | joined: true }.

However, it couples the attribute to the schema, which you might or might not want, depending on your use case. In this mailing list post, for example, Jose suggested to put the computed values (or functions to compute it) where they are needed only.

1 Like

Thanks for the reply. It sounds like I have two options:

  • Convert the struct to a Map, then add the key there.
  • In my ViewModule when creating the json map call a standalone function that returns the value I need.

My spidersense says the second option is better. What’s your opinion?

Your spidersense seems to be right :smile: If it is only a presentation concern, it would be perfect to put it in the view module. You would need to convert the struct to a map anyway if you use the json function.

1 Like