ecto_morph icon indicating copy to clipboard operation
ecto_morph copied to clipboard

Extract the recursion schema

Open Adzz opened this issue 3 years ago • 1 comments

Right now we have validate_nested_changeset where we have defined an interesting traversal for changesets. It

  1. Ensures each step in the given path is a changeset
  2. will handle has_many / embeds_many by applying the function to all elements
  3. Sets errors correctly (parent valid: false, and bubble error messages back up)
  4. handles the merging back in of changes.

This is a really handy traversal for any operation where we might want to apply some change arbitrarily deeply. We currently use it for validations but if we can extract the traversal and supply a fun to run at each leaf that would allow allll the functions.

For example

# Instead of
EctoMorph.validate_nested_changeset(changeset, [:path, :to, :my, :change], &validate_changeset/1)

# We could
EctoMorph.map(changeset, [:path, :to, :my, :change], &validate_changeset/1)

# Allowing more:
EctoMorph.map(changeset, [:path, :to, :my, :change], &put_change(&1, :key, "A new value"))

# If we had a default of all or a way to say "visit all nested changesets" we could do things like:
EctoMorph.map(changeset, &into_struct/1)
# though this feels more like a reduce than a map...

It would also be really cool if we could use a KeywordLens as a path. and get more compact paths.

Adzz avatar Apr 05 '21 14:04 Adzz

This has kind of been done with the private EctoMorph.map function but to make it work with validate_nested_changeset and with validate_required we had to do shenanigans when the nested changeset does not exist in changes.

Maybe we can make a public version that's more sensible.

Adzz avatar Apr 22 '21 17:04 Adzz