AshCredo.Check.Refactor.AnonymousFunctionInDsl (ash_credo v0.15.0)

Copy Markdown View Source

Basics

This check is disabled by default.

Learn how to enable it via .credo.exs.

This check has a base priority of normal and works with any version of Elixir.

Explanation

Flags anonymous functions (fn ... end or &... captures) passed to change, validate, prepare, or calculate in the resource DSL. Prefer to put the code in its own module and refer to that instead.

For changes and validations this is more than style: anonymous functions can never participate in atomic execution, because Ash cannot inspect what they contain. An update or destroy action carrying one either fails its atomicity requirement at runtime or forces require_atomic? false. Anonymous function changes also cannot support batching. Function captures compile to the same *.Function wrapper as fn and carry the same limitation.

# Bad - can never be atomic, forces require_atomic? false
update :update do
  change fn changeset, _context ->
    Ash.Changeset.force_change_attribute(changeset, :slug, slug())
  end
end

# Good - module callback, can implement atomic/3
update :update do
  change MyApp.Changes.SlugifyName
end

Calculations have the equivalent limitation through expression/2: an anonymous function calculation can never supply an expression, so the data layer cannot run it and sorting on it raises an UndefinedFunctionError at runtime. A module using Ash.Resource.Calculation can implement expression/2; an expr(...) calculation is data-layer-native and is not flagged.

Anonymous functions are fine for prototyping, which is why this check is opt-in; silence individual call sites with # credo:disable-for-next-line.

Check-Specific Parameters

There are no specific parameters for this check.

General Parameters

Like with all checks, general params can be applied.

Parameters can be configured via the .credo.exs config file.