Skip to content

Instantly share code, notes, and snippets.

@pinetops
Created April 15, 2025 20:14
Show Gist options
  • Save pinetops/e4859594d66e6830c15f0c276900aca8 to your computer and use it in GitHub Desktop.
Save pinetops/e4859594d66e6830c15f0c276900aca8 to your computer and use it in GitHub Desktop.
Remember that in addition to the prior instructions, when writing queries and code examples, please adhere to the following guidelines:
General:
- Database access is done using Ash 3.0/AshPostgres resources
- Don't use Ash resources for in memory data structures unless specified
- Only implement coding standards for new/modified code unless explicitly specified
- Minimal comments (only notable/counter-intuitive), no module level or function level docs
- Always Remove any unused aliases
IMPORTANT - MIGRATIONS:
- NEVER generate migration files or migration code
- DO NOT create files with timestamps like "20240322123456_add_field.exs"
- DO NOT attempt to write migration code in any form
- When schema changes are needed, simply note: "These changes will require running `mix ash_postgres.generate_migrations`"
- Ash handles migrations differently from Ecto - they are automatically generated with the command above
Ash coding standards:
When writing Ash code:
- Use domain functions when accessing data that's primarily in a different domain (don't go through contortions though) or from non domain modules
- Domain functions should be implemented using resource/define in the domain module and calling an action (created as needed) on the resource (Domain module is usually the parent module, but always contains 'use Ash.Domain)
- When implementing queries with Ash.Query, you must 'require Ash.Query' in any module in which you use Ash's query syntax, and then use the Ash 3.0 interface (Ash.read(), Ash.read_one!(), Ash.create() etc. and ! versions)
- When doing individual creates/updates, prefer the following syntax (optionally Ash.update!()/Ash.create!()):
- For updates: `entity |> Ash.Changeset.for_update(:action, %{prop1: value1, prop2: value2}) |> Ash.update()`
- For creates: `Resource |> Ash.Changeset.for_create(:action, %{prop1: value1, prop2: value2}) |> Ash.create()`
- Alternatively, for attribute-by-attribute updates: `Ash.Changeset.for_update(entity, :action) |> Ash.Changeset.set_attribute(:prop, value) |> Ash.update!()`
- Do NOT use the pattern: `entity |> Ash.Changeset.for_update(:action, %{prop1: value1})` as this is not the preferred approach
- in general ash data operations without ! return tuple with status :ok/:error with ! returns entity directly
- For bulk operations, use Ash 3.0 syntax (! optional):
- Ash.bulk_destroy(records, :destroy, %{}) - do NOT add atomic: true as a separate parameter
- Ash.bulk_create(records, Resource, :create, return_errors?: true) - action options go directly in the function call, not in a separate map
- When building an Ash Query set_argument should be called before for_read (etc.)
- When using Ash.filter(...) queries do not need to be wrapped in expr(), but when using filter in a resource declaration you do need to wrap in expr() When using a select operation, any fields not selected or relationships not loaded will return %Ash.NotLoaded{} instead of nil
- NEVER generate database migrations
- NEVER include migration code in your response
- When adding/changing database fields, simply state: "Run `mix ash_postgres.generate_migrations` to create the necessary migrations for these changes"
Generic Actions and Action Modules:
- When creating generic actions, always use `Ash.ActionInput.get_argument/2` consistently to access input arguments
- For action modules that implement `run/3`:
- Return `{:ok, result}` or `{:error, reason}` consistently
- Place them in a dedicated directory (e.g., `lib/domain/actions/`)
- Keep them focused on a single responsibility
- For domain functions that delegate to actions:
- when using 'args: [:arg1, :arg2], remember these translate into positional function arguments:with'
General Elixir:
- no @doc for private functions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment