Ecto - prevent data modification

I’m currently working on an Phoenix Project and been having some trouble getting validaition sorted out.

Lets say were having a blunt comment and post schema.
And now lets say you can lock the Post, so our post now has an boolean field named locked.
Now we want to prevent modification of the whole thing so no posts can be inserted, updated or deleted.

Ok got that, just write some validation check if the flag is set and add an error if its locked.
All good and fine as long a changeset gets created.

But for deletions for example its no longer required to have a changeset, you could just take a struct to the Repo and no validation is run whatsoever, et voilà the damage is done.

[TL;DR] So the real question is how can i make sure that data stays consistent even if no changeset is created or enforce changeset creation?

You can’t. If you want to make sure only records with a certain property can be modified/deleted, you need to enforce this every time you make a call that could touch one of your locked entries.

For deleting records, you can use Repo.delete_all/2. Since delete_all takes a queriable, you can easily create a function that adds the »scope« of unlocked records like so:

def unlocked_scope(queryable),
  do: where(queryable, [q], q.locked == false)

Alternatively, you could enforce this by using database constraints. Add another table with your locked posts’ ids as foreign key and the database will make sure you can’t delete them.

1 Like