acrolink
Here is an example of a custom validation:
@our_url "https://our-bucket.s3.amazon.com"
def changeset(struct, params \\ %{}) do
struct
|> cast(params, @required_fields)
|> validate_required(@required_fields)
|> validate_from_s3_bucket(:url)
end
def validate_from_s3_bucket(changeset, field, options \\ []) do
validate_change(changeset, field, fn _, url ->
case String.starts_with?(url, @our_url) do
true -> []
false -> [{field, options[:message] || "Unexpected URL"}]
end
end)
end
This can be written in the schema definition file. But where to write custom changeset validation functions which test database tables (of other models) for certain values and based on that data flag the transaction as valid or not? I guess making Ecto queries for B inside schema definition of A is not the correct way to do it. Any ideas? Thank you.
Example / Clarification
I have this in my schema definition:
def changeset(record, attrs) do
record
|> cast(attrs, [:issued_at, :due_for_return, :returned_at, :fee, :fee_paid_at, :book_id])
|> validate_required([])
|> validate_book(:book_id)
end
defp validate_book(changeset, field) do
case changeset.valid? do
true ->
book_id = get_field(changeset, field)
case Repo.get(Mango.Books.Book, book_id) do
nil -> add_error(changeset, :book_id, "Book not found..")
book -> {:ok, book}
case book.status do
:available -> changeset
_ -> add_error(changeset, :book_id, "Book is already out..")
end
end
_ ->
changeset
end
end
As you can see I am doing some Repo query validation against some other model (books). My question is this the place do this or should I move all of this outside of my schema definition?
Trending in Questions
Hey guys,
I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly
Do you guys have any suggestions what is the best prac...
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
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
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
- #deployment
- #library
- #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 4- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
idi527
I usually avoid making request to a database inside changesets. Instead, I use more explicit multis or transactions. So your second example I would write as:
jeremyjh
Changeset validation functions should be limited to pure functions that use the data available to them in the Changeset and arguments you pass. They are not “models”. Business rules that require data access, messaging etc should be implemented in another module - if you are using Phoenix it would be a context module - but regardless its just a module with functions.
Laetitia
What about using Ecto.Changeset.prepare_changes ?
I will run some validation and returns an invalid changeset if it failed.
pierreabreup
@Laetitia
Changeset.prepare_changesworks exactly you said, but I guess the @acrolink point is more about the right way to design this code for validation. There is no strict boundary about where the code must be written (in the same module or another module).In my projects, I always prefer to place business rules inside another module. For me and my team, it sounds an organized way to split responsibilities, works very well to us.
Of course, this strategy comes a side effect: you will have data validation in two different places for the same entity (post, user, comment, question, etc). You have to feel comfortable with it.