johmue
Hook function in Ecto.Schema to set virtual fields when querying a Schema struct from the data store
In this talk on Ecto the speaker recommends to calculate persistent fields from virtual Ecto.Schema fields that come in from user input in a changeset.
In his example there is an Ecto.Schema like
defmodule MusicDb.Track
...
schema "tracks" do
field :title, :string
field :duration, :integer
field :duration_string, :string, virtual: true
timestamps()
end
The duration field holds the duration in seconds persistently in the database. The duration_string is used to hand in the duration time from user input as a string, For example duration_string comes in as "3:25" in the changeset which would be piped through a function that sets the time_in_seconds field to 205.
So far so good. But how do I go the way back? When I query a Track my duration_string field would be nil. Is there any way to install some hook function in the schema where the Track struct is piped through whenever I query a Track so that I can calculate and set duration_string?
Marked As Solved
dimitarvp
Because this community does not like implicit / magic behaviour. We like things explicit. ![]()
Plus, this seems like a perfect candidate for a Phoenix context: make a function like Tracks.load which takes care of the duration shenanigans and you’re in a good place.
Also Liked
hauleth
There is list of possible solutions:
- persist field
- create view with value computed
- create custom Ecto type
- create function to transform one to another
- create comparison function in DB
- create custom type in DB
These are few of possibilities. Which one is the best for You depends on what you need.
LostKobrakai
There’s even the option of using preload functions:
https://medium.com/rekkiapp/how-to-use-data-spanning-multiple-data-sources-in-elixir-50f39c87d8fc
benwilson512
I’d consider looking into Boundary — boundary v0.10.4. It can allow you to enforce programmatically where you allow things like Repo calls.
This general problem is part of why I’d like to take some time to make Dataloader more ergonomic outside of Absinthe. Over fetching / under fetching is really quite a hard problem to tackle.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








