Skip to content

docs: explain when and why to use before_action? on validations - #2914

Merged
zachdaniel merged 1 commit into
mainfrom
docs/before-action-validations
Sep 4, 2026
Merged

docs: explain when and why to use before_action? on validations#2914
zachdaniel merged 1 commit into
mainfrom
docs/before-action-validations

Conversation

@barnabasJ

Copy link
Copy Markdown
Contributor

Summary

before_action? on validations was only documented mechanically ("the validation will be run in a before_action hook") with no explanation of when or why you would want it. The original 1.x name, expensive?, carried the intent, but that was lost in the 2.0 rename.

  • Validations guide: new before_action? Option section explaining that validations normally run when the changeset/query is built, and the two reasons to defer one to execution time:

    1. It is expensive (runs a query, calls a service) and changesets are built far more often than executed. AshPhoenix.Form.validate/3 rebuilds the changeset on every change event, so a querying validation would otherwise hit the database on every keystroke.
    2. It needs to observe state at execution time, inside the data layer transaction, right before the write.

    Also lists the trade-offs: errors surface only on submit, it cannot be atomic (require_atomic? true fails, bulk falls back to :stream), it runs after before_transaction/around_transaction hooks, only_when_valid? is checked at hook time, and delay_global_validations? is the same thing applied to all global validations.

  • Actions lifecycle guide: the "Inside Transaction" bullet listed action/global validations, contradicting the paragraph below it which says they run during changeset creation before the transaction. Corrected to hooks plus before_action? validations.

  • Option docstring in Ash.Resource.Validation expanded, DSL cheat sheet regenerated.

Behavior verified against Ash.Changeset.validate/5 (hook wrapping), Ash.Changeset.with_hooks/3 (transaction boundary) and AshPhoenix.Form.validate/3.

Test plan

  • mix spark.cheat_sheets regenerated cleanly
  • mix test test/resource/validation_test.exs test/actions/bulk/bulk_update_test.exs test/actions/update_test.exs (105 passed)

🤖 Generated with Claude Code

Adds a section to the validations guide covering the two reasons to defer
a validation to a before_action hook: avoiding repeated expensive checks
when the changeset is rebuilt (e.g. on every form change), and running
the check inside the transaction at execution time. Also lists the
trade-offs (errors only on submit, not atomic, runs after
before_transaction hooks).

Fixes the actions lifecycle guide, which listed validations as running
inside the transaction while the next paragraph said they run before it.

Expands the option docstring and regenerates the DSL cheat sheet.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@zachdaniel
zachdaniel merged commit 81bc148 into main Sep 4, 2026
51 checks passed
@zachdaniel

Copy link
Copy Markdown
Contributor

🚀 Thank you for your contribution! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants