Skip to content

Add required!/1, ash_required/1, and ash_required!/2 (issue #261)#707

Open
dallingson wants to merge 2 commits intoash-project:mainfrom
dallingson:main
Open

Add required!/1, ash_required/1, and ash_required!/2 (issue #261)#707
dallingson wants to merge 2 commits intoash-project:mainfrom
dallingson:main

Conversation

@dallingson
Copy link

Pull request: Add required!/1, ash_required/1, ash_required!/2, and required_error/2

Closes #261


What

Adds custom expressions required!/1 and ash_required/1 for presence in queries, and ash_required!/2 plus required_error/2 for required-field validation that returns Ash.Error.Changes.Required when a value is nil.

Why

There was no built-in way to express "required/present" in filters and calculations without not is_nil(...), or to get Ash's standard required error from the data layer when a value is nil.

How to use

Presence in queries (filters/calculations):

# Instead of: not is_nil(post[:title])
filter(ash_required(:title))

# Or with required!/1 (same meaning)
filter(required!(:title))

Required-field validation (returns Ash.Error.Changes.Required when nil):

change fn changeset, _context ->
  Ash.Changeset.require_change(changeset, :title, &AshPostgres.Functions.RequiredError.required_error/2)
end

When the value is nil, Ash uses required_error/2 and the data layer returns the standard required error.

Changes

  • required.ex / ash_required.ex – Custom expressions required!/1 and ash_required/1 for presence in queries.
  • required_error.exrequired_error/2 and data-layer integration so validation returns Ash.Error.Changes.Required when nil.
  • ash_required.ex (expressions)ash_required!/2 expression that uses the required-error path when the value is nil.
  • data_layer.excan?(:required_error) and registration of the new functions/expressions.
  • ash_functions.ex – PostgreSQL ash_required/1 in migrations so it's available in SQL.
  • config.exs – Registered the new custom expressions.
  • Docs – New content in documentation/topics/advanced/expressions.md.
  • Tests – Filter, aggregate, calculation, and required_error_test.exs coverage.

Contributor checklist

Leave anything that you believe does not apply unchecked.

  • I accept the AI Policy, or AI was not used in the creation of this PR.
  • Bug fixes include regression tests
  • Chores
  • Documentation changes
  • Features include unit/acceptance tests
  • Refactoring
  • Update dependencies

…ct#261)

- required!/1 and ash_required/1: custom expressions for presence in
  queries (replacing not is_nil(...))
- PostgreSQL ash_required/1 in ash_functions.ex for filters/calculations
- Data layer can?(:required_error) and ash_required!/2 (RequiredError):
  when value is nil, return Ash.Error.Changes.Required; required_error/2
  for the error message
- Docs and tests for the new expressions and required_error
@zachdaniel
Copy link
Contributor

I don't see any particular value in required, and ash_required. Fundamentally we just need the required error logic.

SQL function, config, and tests
Keep ash_required!/2 + required_error/2 and
:required_error data-layer capability, and
update docs accordingly
#
# SPDX-License-Identifier: MIT

defmodule AshPostgres.Functions.RequiredError do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should also live in ash core. We would just need to add support for it in ash_sql, update the dep here, and then add it to the capabilities list.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love to help get this implemented in ash core if you would like. Do we need to have this in a separate issue for ash core?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can also go in and make changes to ash_sql if you would like.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please feel free 😄 There are other functions in AshSql and Ash core that you can use as reference. LMK if you have any questions! So first the change in Ash, second the change in AshSql, third the change in AshPostgres.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, just to clarify. What changes need to be made in ash_sql? As of right now I know that I am moving the required_error to ash core and then updating ash_sql and ash_postgres. I just want to make sure I know what needs to be changed in ash_sql. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, actually 🤔 You wouldn't make any changes in AshSql come to think of it. You can modify the SQL implementation file in ash_postgres to add a handler for the new function in ash core. So we just need to first add the function to ash, and then add an expression handler here 😄 Sorry for misleading.

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.

Add ash_required/1 function in the ash-functions extension, and a mirrored required! function in ash expression syntax

2 participants