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

Multiple checkbox form

I'm trying to implement https://fly.io/phoenix-files/making-a-checkboxgroup-input/ for a field that is a {:array, ;uuid}. When generating the form, using AshPhoenix, I can see that form.data and form.source have values inside the field that will be used in the multi checkbox field. However @value is always empty, so I can't tell if a given checkbox should be checked or not. I circumvented the problem by passing defining the checked flag as a third element in the options array....

How to list calculation without raw queries

I have a resource with attributes scheme and url, and a calculation :full_url. The calculation basically just concats the two with "://" in between. If I want to get a list of full urls for all my resources, I learned I can do this MyResource |> Ash.Query.load(:full_url) |> Ash.list!(:full_url). But I can't figure out how to do this as an aggregate or an action. Is it possible? Is this the right way to do it? I think aggregates always require a relationship.

Relying on metadata on "public" API an anti-pattern?

Is it generally considered an anti-pattern to rely on data that's stuffed inside metadata on a resource, especially in a "public" API? When I say public API, I mean generally following the pattern of Resource actions being used only internally in their domain and Domain actions being used externally of the domain. For example, say I have an MyApp.Accounts.Session resource that puts a token in the metadata during the create action since the token is hashed before inserting into the DB. The public API on the domain exposes it through an Accounts.create_session action. Do we really want callers to be doing Resource.get_metadata on the result in that public context to get the token or is that an anti-pattern? Is there a better way to be surfacing that information? For example: ```elixir def my_caller_func do # ... other code...

How to use field policies to show/hide fields in a UI?

I am diving into field policies to make some data available for certain subscription plans. When the field returns %ForbiddenField{}, Phoenix HTML doesn't know how to deal with it. What's the best practice for doing this in the UI? The only thing I can think of is to use is_struct(resource.field, Ash.ForbiddenField everywhere....

How to load a nested relationship with a tenant?

I'm a beginner with Ash and essentially I'd like to lookup an organization while loading some relationships, something like this: ``` Sites.Organization |> Ash.Query.load(user_roles: [:user])...

ash read_one bug?

https://hexdocs.pm/ash/Ash.html#read_one/2-examples Ash.read_one(Submission, id: submission_id) does not work ```...

Single attribute join via belongs_to

What is the correct way to join a subset of attributes to a resource through a belongs_to relation? For instance, with post has many users and post belongs_to user, i want only the public?(true) fields joined onto the post struct does this belong in a prepare() maybe? or is it a calculation?...
Solution:
you can do that with a calculation ```elixir defmodule Post do ...

Confirmation

I'm a bit confused with confirmation, following https://hexdocs.pm/ash_authentication/AshAuthentication.AddOn.Confirmation.html I have ``` confirmation :confirm do monitor_fields [:email]...

AshAuthentication trusted audiences

Hello, I'm in the process of deploying a multi-tenant application internally in my company. I'm authenticating users against Microsoft Entra ID using the OAuth2 strategy. We have two tenants that I need to allow users to authenticate from and wish to use the trusted_audiences to ensure that a user signs in from one of the tenants, but reject all others. I have set it up as described in the docs, but when I test it locally by only allowing a "fake" audience in the list of trusted audiences, I'm still authorized to login. Do I have to do anything else to make this work, or have I misunderstood something? ```elixir...
Solution:
So it seems like my options are: 1. Change to using OIDC strategy. Supports trusted_audiences but struggles with using the /common/.well-known/openid-configuration endpoint because it contains a placeholder {tenantid} in its issuer which is not supported natively by assent. This cause the issuer validation to fail, because the issuer in my token contains my real tenant-id. Could work, but requires a custom strategy? 2. Continue with using OAuth2 strategy. Works out of the box with multi-tenant applications, but needs to implement a custom trusted_audience handler either as a change function or in auth controller success callback (and then deny access unless audience matches allow-list)....

where's the best place to run possibly long running queries on the DB after an insert / bulk insert?

I have a materialized view which I need to refresh when I either do a bulk load on a table via bulk_create, or an individual insert on it. My initial idea would be to trigger an oban job via an after_action, but just want to clarify how this works for upserts etc....

ash_postgres.generate_migrations not working

It recently stopped generating migrations when there are attribute changes to resources. I get "No changes detected, so no migrations or snapshots have been created" I upgraded ash (3.5.24), ash_postgres (2.6.9) and ash_authentication (4.9.4), etc. but it didn't help. In fact, when I removed the "uuid_primary_key :id" line from Token and ran mix ash.codegen remove_id_from_tokens, it still insisted there is no change detected. ...
Solution:
so Token needs to be in some domain, probably Accounts, and Accounts needs to be mentioned in :ash_domains. ``` in config/config.exs import Config ...

AshAuthentication Testing

Need help setting up a function that mocks a logged in user in my conn. I'm using magic link authentication, this is what I've got so far: ```elixir...
Solution:
```elixir def log_in_user(conn, user) do strategy = AshAuthentication.Info.strategy!(MyApp.Accounts.User, :magic_link) {:ok, token} = AshAuthentication.Strategy.MagicLink.request_token_for(strategy, user) user = Accounts.sign_in_with_magic_link!(%{token: token}, authorize?: false)...

Unsupported expression in Elixir.AshPostgres.SqlImplementation query: `datetime_add`

Can't quite tell what I'm doing wrong here. The OrgSubscription is a many_to_many resource that connects Organization to SubscriptionPlan. ```elixir...
Solution:
You may need to use a fragment

No such input for atomic_update

Suppose I have a resource with attribute: ```elixir attributes do ......

Using no attributes to use a parent_type / parent_id style table as a join table

I have this table: ``` attributes do integer_primary_key :id ...
Solution:
Ok for anyone else coming across this post because they want to use no_attributes? true to do some complex mapping, here is the gist of it: - You can do a has_many or has_one to any App.Domain.Resource with some prereqs: - There must be a tangible path mapped up back to what you want - In my case I had...

How to model this runtime config in Ash?

What's the normal way to have a singleton resource that is saved in postgres, but has a read-only copy in ETS? I'm trying to think of how I might migrate one part of my app to Ash. In my app I have a global runtime configuration struct. Basically this is a config that admin users should be able to modify at runtime via a json API (or maybe the Ash admin UI 🤔) and it's supposed to affect the behavior of the system at runtime. Right now this config has a table in postgres with a custom unique index (true). This means that only one row is allowed in the table. The table itself just has one column which is a JSONB type. When the app starts up it reads this config and saves it with Application.put_env. Then in various places in the app I just fetch the config from the application env and pattern match out what I need. I could probably use persistent_term, but it's not a big struct. When a change is made to this config struct I update the database row and use Oban.Notifier to broadcast a message to all other instances of my app to tell them to refresh their application env cache of the config. What would be the Ash way to implement this? It doesn't have to work exactly like this. This is the best I came up with, but I'm happy to hear alternatives 🙂...

Test initialization takes more time than expected

I'm doing a green field project in Ash and it's been great so far. I'm feeling a bit lost when it comes to tests and their speed though. It takes about six seconds to run the test suite consisting of six tests, and that's enough for me to lose focus and start doing something else. I measure this by running time mix test. Elixir's test runner says it takes 0.5 seconds to run all tests, so something happens before the test runner starts. Right now my hypothesis is that `Getting extensions in cu...

"ERROR 42704 (undefined_object) type "vector" does not exist" during migration.

Hello, has someone tried the vectorization on a resource? I encounter a migration error problem. Current setup for vectorization of Post resource: 1. First, created setup_vectorization.ex in folder lib ...
Solution:
And then delete the migrations and snapshots you just generated

Is there any public function to prettify a BulkResult/Change error?

I want to display a :string error message but in this case there is none, i think AshJsonApi translates this errors to a message somehow, is that function public? ```elixir %Ash.BulkResult{ status: :partial_success,...
Solution:
so like AshJsonApi.Error.to_json_api_errors(Domain, Resource, error, :create)

ManualRead for wrapping an API using attribute constraints

I want to wrap an API with a resource. The response from the provider has a bunch of fields that can be "", which I'd prefer to be nil. Pretty sure this can be handled with constraints on attributes when the values are casted. The example in the docs shows manually creating the resource's struct from the API response and using Ash.Query.apply_to/2-3. Will this approach apply the constraints for the returned values doing this? Or is there a better way to make sure the constraints are applied?...
Solution:
I don't think it will cast those inputs, no