Ecto re-validate existing hierarchy

Hi there,

I have an issue with re-validating a hierarchy of models. We have articles and batch. An batch can contain many articles. We can create an article and it will be validated inside the changest/2. But before publishing we have an separate validation, we use changeset_publish/2 for that. When publishing a batch (it includes validating all contained articles) I try to do that with change_publish/2 inside the batch.

The problem is, that I don not change data when validating. I am kinda validating the already persisted data. I managed that cast_assoc uses the changeset_publish of the arcticle, but it is not called, since I am not changing articles. My dirty workaround is to call

Batch.changeset_publish(batch, %{articles: Enum.map(batch.articles, fn(a) -> %{id: a.id} end })

This way he calls the Article.changeset_publish.

Is there a smarter way to enforce that associations are validated as well?
Hope my description is not too confusing :slight_smile:

Use the database constraints, not ecto validations, this is precisely what a good SQL database constrain is designed for. :slight_smile:

Thx for the idea with the db constraints.
Actually I have two definitions of valid. One is in draft mode. There are some fields that are not required while in draft. But before publish they have to be set.

Actually that can be done in SQL Constraints and indexes too! :smiley:

Ecto even has support for it, you can have indexes exist with a ‘when’ condition in the migration, so it only effects, say, rows where publish is false, and another set of indexes when publish is true. :slight_smile:

I use conditional indexesvery often in many places.

I think it is nice with Ecto that fk constraints are being nicely supported. I personally do not like to put to much logic into the db schema. But I remember years ago in the microsoft world that was totally accepted to put all the business logic in stored procedures.

But it is a good hint with the conditional indexes, I have a case where that would be quite handy. I think that is something that is hard to accomplish wihthout the help of the database.

1 Like

Exactly, a lot of this is, quite frankly, impossible to do well on the application side, the database is what knows of the constraints and on the application side it will always be slower, less efficient, and unreliable to try to emulate them. :slight_smile: