maxim
Hi folks,
I’ve written custom types before, but this specific case gives me pause, and I wonder if you could explain your reasoning here when deciding how to split this logic between cast and dump.
I have a list of base-3 integers that I store in the database as a :binary (postgres bytea).
The value that I assign looks like this (up to 127 digits):
[0,2,1,0,2,2,1]
The value database stores looks like this
[0,2,1,0,2,2,1] |> Enum.reverse |> Integer.undigits(3) |> :binary.encode_unsigned
# <<5, 112>>
However, I have to run 3 checks:
- Is this a list?
- Is length in
0..127 - Are all digits in
0..2?
What part of this goes into cast, and what goes into dump?
Here’s what I think, correct me if I’m wrong:
- Cast runs the above 3 checks, but keeps it a list.
- Dump ALSO runs the 3 checks (in case value was assigned without
cast) but converts it into a binary.
However, those 3 things are quite a bit of code. Between 2 guards and an Enum.any? they traverse the whole list a couple of times. If this is correct, am I supposed ignore the fact that I’m running the same logic twice, once for cast and once for dump?
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hello!
Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app.
I creat...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
I’m trying to set up Emacs with elixir-ls via lsp-mode and credo via Flycheck. This should mostly be preconfigured as Flycheck picks up c...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 9- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
NobbZ
I’m not sure where to put the checks, but at least I can tell you that you only need to iterate once, roughly like this:
This will iterate not more than once and not more than the first 128 digits of the list.
Due to the early return it should not become a bottleneck that soon.
maxim
Thanks for a useful tip, will definitely combine count and validation. That said I’m still interested in
castvsdumpreasoning.LostKobrakai
Ecto.Types handle 3 different data representations. Outside data (most often from form inputs, or json fields in the db), runtime data (how your data is put into your structs by ecto and used at runtime) and the database representations as db column.
cast goes from outside data → runtime data
dump goes from anything (outside data or runtime data) → database column data
load goes from database column data → runtime data
For json (map) fields there’s also
json encoding from anything → database json value
cast from database json value → runtime value
The reason why cast/json encoding need to deal with “anything” is because there’s nobody stopping you from inserting data via
Repo.insert_allor manipulating a struct manually and there’s no casting involved. So any validation of correct data needs to be done in both cast and dump, where one converts to runtime data and the other to database column data.maxim
That’s a great explanation, and from what I gather, for the question of “Should we be ok with doing the same work twice, once in cast and once in dump” the answer is “yes”.
And since outside data can also be formatted consistently with runtime data, would it be more correct to say that
cast goes from anything to runtime data
dump goes from anything to database column data
With this in mind, it’s almost always ok to actually call
castfunction from yourdumpfunction, does this sound right? (I know it depends, but I’ve noticed I could do that in most custom types I wrote).ream88
Omg, can this answer please be included in the official Elixir docs? Maybe as a cheatsheet. I’ve never read a better explanation than this one!
axelson
I like visuals so I made a visual to represent @LostKobrakai’s awesome explanation:
And one thing that sometimes confuses (me at least) is that sometimes the “Outside data” and “Runtime data” have the same representation, for example for
Ecto.UUID. Seeing it in this visual form makes the reason behind that easier for me to understand/remember:dimitarvp
Awesome visualizations. Instant bookmark.
gregvaughn
That would be awesome in a documentation PR!
LostKobrakai
Already merged: