krut

krut

Discard invalid embed entries during casting

I am wondering if there is an idiomatic way to discard invalid embed entries during casting, i.e. when Ecto.Changeset.cast_embed/3 is called, as opposed to marking them as invalid, which will in turn make the parent changeset invalid.

As an example - I have a number of nested embedded schemas that are used to cast incoming webhook data, e.g. a Post that embeds_many :comments. These comments can either be active or inactive (e.g. a deleted comment).

The application only cares about comments that are active, which I can identify by using Ecto.Changeset.validate_inclusion/4 on the comment’s :status. However, this will cause the inactive comments to be marked as invalid, which will then make the parent post invalid.

I was thinking it would be nice if I could discard the invalid embeds (for this particular field), and send the post (with only active comments) through, as it would simplify the business logic in multiple areas.

Does this functionality exist in Ecto? Or would this be a kind of anti-pattern / bad approach? Would love to hear any thoughts.

Marked As Solved

cenotaph

cenotaph

Let’s approach SOLID, FP and philosophically

Changeset as correctly named, set of changes. Should only carry and work on the changes. Its scope should start and end with the changes [validation, casting]. It should not mutate the changes.

If the consumer pushes n changes, I have two options, filter before or after I provide it as a change.

then depending on my use case I would validate changes accordingly.

  • I could ask my consumer to send only active records since I am the owner of the contract to decrease payloads.
  • Depending on my payload, I would filter() |> validate() as early as possible before operate()
  • I would have a very specific use case changeset to satisfy the needs.
payload
|> filter_out_inactive_comments(..)
|> Post.bulk_update_changeset(..)
|> update_post(..)

bulk_update_changeset(...) do
  ...
  |> validate_inclusion(...)
  |> validate_length(..)
  |> validate_assoc(..)
  ...
end

Also Liked

oliveiragahenrique

oliveiragahenrique

I think that changesets are not meant to be used like that.

You may be better served by calling the classic Enum.filter/2 before Ecto.Changeset.cast_embed/3, because all you want is just that, filter specific elements from a set of elements! :smile:

krut

krut

Thank you for such a detailed explanation and example! :pray: That all makes sense and is very helpful.

I had been filtering in the operate() stage, which was complicating things and causing unnecessary duplication.

I think I will want to filter “before” then…for some reason I wasn’t considering that, and thinking that the casting should come first. Thanks again!

krut

krut

Thank you! I suspected that might be the case :sweat_smile:I think you’re spot on with filtering before.

Where Next?

Popular in Questions Top

openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New

We're in Beta

About us Mission Statement