Ash Framework

AF

Ash Framework

The Elixir backend framework for unparalleled productivity. Declarative tools that let you stop wasting time. Use with Phoenix LiveView or build APIs in minutes for your front-end of choice.

Join

support

showcase

today-i-learned

How do I do this SQL UPDATE-query in Ash?

I want to update a row in a database table if it exists, and otherwise return an error. In SQL I would do something like this:
UPDATE hats SET activation_token = null, activated = NOW() WHERE activation_token = ...
UPDATE hats SET activation_token = null, activated = NOW() WHERE activation_token = ...
...
Solution:
```elixir require Ash.Query # needed for filter bulk_result = Hats...

Return resource A from an action on resource B

I am working on an invite-only application. I have a User resource and an Invitation resource. I would like to create an :accept_invitation action which validates an invitation record, creates a user, and returns the user. This is what I have attempted so far: ```elixir on the invitation resource update :create_user_with_invitation do...
Solution:
This seems to have done the trick: ```elixir defmodule Dreng.Changes.ValidateInvitation do use Ash.Resource.Change ...

How to properly handle relationships and references

Right now i have this 3 files and to avoid leaving relationships hanging in my delete I manually go through each relationship and delete it. The reason I have the other 2 (update and create) setup the way they're is because I was following this tutorial from the docs, but it doesnt have anything on destroy, and just putting ` change manage_relationship(:ticket_ids...
Solution:
Just had to add
references do
reference :team, on_delete: :delete
reference :ticket, on_delete: :delete
end
references do
reference :team, on_delete: :delete
reference :ticket, on_delete: :delete
end
on the union/intermediary table, and then I can delete teh custom destroy action, heres the final files in case some needs them later...

JSON API patch without bulk update

Is is possible to do a PATCH with ash_json_api that will do an update that doesn't use bulk_update? I'm wanting to write an update policy that's essentially a runtime policy (i.e. it needs access to the object that's changing in order to validate). Poking around source code though, it looks like PATCHes are always implemented with bulk updates?

Conditional Relationship Creation

I'm trying to create a profile when a user registers, but only if one doesn't already exist. I tried using manage_relationship/4 with type: :direct_control and it does create the profile, but if the user already has one - with more data fulfilled - it overwrites it with the partial available data at user registration — which is not ideal. Is manage_relationship/4 the right way to handle this? Or should I use an after_action hook to conditionally create the profile?...
Solution:
That's right, this makes it ```elixir change after_action(fn changeset, user, context -> profile = Ash.load!(user, :profile) |> Map.fetch!(:profile)...

I found possible bug with Ash.DataLayer.Mnesia in form validation

I'm writing the Tunez code using Mnesia, and I came across this difference. ```elixir form = AshPhoenix.Form.for_create(Tunez.Music.Artist, :create) AshPhoenix.Form.validate(form, %{name: "Best Band Ever"}) # returning valid ...

How to implement an override table?

Hey. Business wants to override a table that I'd like to keep free of tampering. So I'm thinking to create a the_table_override that can be merged at some other stage. But of course I'd like to keep the Ash Resources in sync schema wise. So if I chance the main one the other follows. Is there a way to create a new resource that mirrors another one at all times? I imagine macros is the answer, but maybe there's another path?...

Manual relationship in belongs_to

Hi! Is there any reason there is no way to have a manual relationship in a belongs_to block? Is it because that one by default creates the attribute? I'm doing a Stripe wrapper that generates custom dependencies, and some relationships are belongs_to-like and some are has_*-like. And would love to preserve the semantics....

How to concatenate strings on related column like STRING_AGG with sort?

I have a simple has_many relation with parts:
has_many :parts, Part
has_many :parts, Part
...

Idiomatic way to test AshOban trigger conditions

As the title state, what's the best way to test the condition that would trigger an AshOban trigger?

Use full text search in fields

Newbie here, is there a way I can fields defined as full text search fields?

ash_oban discarded jobs with `trigger_no_longer_applies`

I'm using ash_oban, and I keep seeing quite a few jobs getting discarded with ** (Oban.PerformError) MyApp.SomeDomain.SomeResource.AshOban.Worker.SomeTrigger failed with {:discard, :trigger_no_longer_applies}. It's quite odd because as far as I can tell, it seems like the jobs are running when I'd expect them to, however I see my oban jobs littered with many of these discarded jobs. I'm curious if this is something that is common/expected in ash_oban, or if it could potentially signal some deeper issue with my setup. I've started observing some very strange timing bugs recently (the details of which I won't go into here) which are making me suspect these errors could be indicative of something wrong on a deeper level. I'm hoping to at least get a feel for how to interpret these errors, which I can then use to go debug the setup I have....
Solution:
It happens if jobs are completed in between the scheduler running it's read query and scheduling the jobs. https://hexdocs.pm/ash_oban/dsl-ashoban.html#oban-triggers-trigger-trigger_once? and when the second job runs the read action doesn't return the record anymore because the previous job already set the state to something else, which makes the where condition not apply anymore. If that happens the job is discarded...

Tenancy create schema concurrency errors on Tests

```elixir 64) test Organization resource actions can create organization without slug (no validation currently) (.Accounts.OrganizationTest) test//accounts/organization_test.exs:49 match (=) failed code: assert {:ok, organization} = Accounts.create_organization(attrs, authorize?: false)...

Is it possible to use LangChain.NativeTools?

I tried creating the following resource to build a simple lookup prompt action. The idea is that someone can put some search term into it and have the LLM look up the NPI registry information using a Google search. The LangChain docs show a usage example here and I tried recreating it with an Ash resource here: ```elixir defmodule Prism.NPI.Lookup do use Ash.Resource, extensions: [AshAi], domain: Prism.NPI...
Solution:
It's slightly more verbose but converting it to a generic action wasn't so bad: ```elixir defmodule Prism.NPI.Lookup do use Ash.Resource, extensions: [AshAi], domain: Prism.NPI...

In ash oban infer/bypass tenancy for action

Hello, I have a AshOban trigger that runs an update action. In the update action you cannot specify multitenancy :bypass so it errors out with changesets require a tenant to be specified this also if I'm specifying a read action that bypasses the tenancy. What is the best practice here allow global true in the multitenancy block?...

Using a relationship in a validation (atomicly)

I couldn't easily find this in the docs, but can use refer to relationships (easily) in validations? For example, we have widgets with a width and x property. Widgets belong_to a Scene that have a width property. We want to make sure that a Widget's x + width property is less than it's parent Scene's width? I assume you need to use a custom validation for this. But can you make that custom validation atomic somehow?...

How to use `after_action` when soft delete is enabled in global `Change`

Hi, Sorry! I have a global change that i am using inside my many resources! the problem i have when i use soft delete Ash.destroy!(Ash.get!(MishkaCms.Runtime.Site, id)) it is not triggerd It does not work ```elixir defmodule MishkaCms.Runtime.Resources.Changes.SendToOban do...
Solution:
So it could be that it uses the atomic callback depending on how you call your action and your atomic implementation isn't doing anything. But as your change only has an after_action and that's allowed in the context of atomics you can try this: ```elixir defmodule MishkaCms.Runtime.Resources.Changes.SendToOban do use Ash.Resource.Change...

Drop unneeded column via codegen

Hi! I'm refactoring a resource and removed all references to office_id from my ParkingLot resource, replacing it with a belongs_to :site relationship. However, when I run mix ash.codegen, the migration generator is renaming the column instead of dropping the old one and creating a new one: ``` Like this instead of drop/add rename table(:parking_lots), :office_id, to: :site_id...
Solution:
When I clicked no, the generator added the new column but left the old one, which is fine to be honest. What I ended up doing is first removing all references of the old relationship, then running codegen. This removed the old column. Then I added the new relationships to the new table and ran codegen again. Worked perfect, and I kinda like that it forced me to make more granular migrations to drop and then create.

Redirect on successful authentication

This seems like a trivial issue but I can't seem to figure out how to do it. Suppose: 1. A user clicks the account button in the navbar but is currently logged out. 2. Ash authentication helpers redirect them to /sign-in. 3. They log in successfully....