fireproofsocks
I’m working on a table to store shipping addresses. I would like to add a fingerprint of each address so that I can more easily tell whether or not a given address has already been added. For simplicity, let’s assume that I’ve worked out a nice fingerprinting algorithm to normalize my addresses and identify them via a single string… let’s say this function is named simply fingerprint(address).
My question is about Ecto and changesets: how and where can I add this field to the database record when I save it? I’m unclear on how the cast and other functions are working inside the changeset function.
If I try to save a new address and its fingerprint matches an existing address, the save operation should fail.
If I try to edit an existing address and change it so it matches an existing address, the update operation should fail.
Any help on this would be appreciated… I’m having a hard time wrapping my head around where to add this and how to think about it in an idiomatic way. Thanks!
Trending in Questions
Other Trending Topics
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
- #ai
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #security
- #performance










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
kokolegorille
Probably something like this…
It is not tested, and fields might not correspond to your structure, but You can get the idea… the 2 last lines from changeset are important.
axelson
I’d also recommend you store the
fingerprintin the database and add a unique constraint and a non-null constraint on the column.fireproofsocks
Whoa. Mind blown. First off, thank you – this is way further than I would have gotten even after pouring over the Ecto docs. This code does execute, but the “fingerprint” value does not get set. I can test the
create_fingerprint()function and verify that it returns a string value when given a map representing an address. I confess that I do not understand much of anything (including the syntax) of thedefp fingerprint()function in your example. Can anyone walk me through that code? Or maybe someone can spot why that value isn’t persisting?As always, many thanks.
kokolegorille
You might show your schema, and migration file. Be sure :fingerprint field exists, as string…
You might also insert some IO.inspect in your pipeline to show the changeset, like so
The function fingerprint take a changeset, and if it is valid, it should persists the change.
If it is clearer, You could have used pattern matching, like so.
BTW Try to change the name of the function to generate_fingerprint(), just to be sure it does not conflict with the field name.
fireproofsocks
Here’s my schema file – the
get_fingerprint()function seems to work when I test it iniex, so I’m thinking I’ve missed something in thecast()or other functions insidechangesetsince I’m not fully understanding the pieces of that.Are there times when you would want to define a field in the database but not list it in the fields passed to
cast()?kokolegorille
Do not cast :fingerprint… it will be calculated
fireproofsocks
I tried omitting that, but the result is the same. I guess I don’t understand what
cast()is really doing (or the@fieldsmacro for that matter)… even if I include a value for for thefingerprint, my expectation is that it would be overwritten anyhow.kokolegorille
The @fields is just equal to a list of fields, as your [:street1, :street2, :city, :state, :zip, :country, :fingerprint]
cast() transforms data from the outside world, to the inner struct.
Did You get some logs from IO.inspect()? I am curious to see how the changeset looks.
kokolegorille
This should not work… as it should be a field
You should use
In the example I gave, whatever is the shemas, and address is just a field of %Whatever{}
You might find ecto changeset structure here. From docs…
jordiee
You can also use get_field(changeset, key, default \ nil) to check against changes and then the changeset data for your address prop. You issue may be be that address is not in the changes obj.