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.
JoinAF
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.
JoinHow to handle submit-only actions without data layer but with validations?
Hi everyone, I'm just getting started with Ash and ran into a challenge when trying to build a LiveView form that validates input and then sends the data to an external API, without using a data_layer.
I'm using a create action with validates and a change/3 callback for the external logic. The issue is: change/3 is called before validations are applied, and changeset.valid? is already true, so my logic executes even when the input is invalid.
Since I'm not using a data_layer, before_action and after_action hooks are not triggered — which would have been ideal for running the API call only after validation....
map datatype type form with ash_phoenix.gen.live
attribute :data, :map do
public? true
end
when creating a new element of this resource I had to leave data blank inserting JSON in the browser was not possible...
Actor attribute in relationship filter expression is NULL
I have an Actor Resource that has a project_id attribute and it has been used successfully in policies many times.
But for some reason in this relationship it is always NULL:
```elixir...
Solution:
Can I see the code where you're doing that? Are you specifying the actor theere?
destroy action based on filters
I currently have a read action and I pass the result to the default destroy action, is it possible to have a destroy action which includes the read part? It seems like destroy only works when passing along the objects
So basically I want to destroy the results of
```elixir...
Solution:
okay so you want to call it via a code interface. you can add the option
require_reference?: false to the code interface, and then provide your own filters etc. in the action. (make sure to specify filters or it will delete everything)manage_relationship does not insert
```ex
create :register do
accept [:name]
argument :members, {:array, :map}, public?: false, default: []
...
Policies for `create` upsert actions
I have a
create do upsert? true end type of action that I'd like to put a policy on. However, I get a warning that says I can't add policies to create actions, basically because the data doesn't exist yet to be able to authorize against. So this is a two part question.
Question 1:
When upserting, there is data. Is there a way to authorize that? Maybe I'm relying too heavily on upserts.
...Solution:
You can make it an update action on
Siteredirect from oauth callback
I am currently using google oauth sign on but I want to enable return to functionality.
case conn.params["returnto"] do
"/" <> = return_to -> redirect(conn, to: returnto)
-> redirect(conn, to: ~p"/")...
Google/OAuth Passing State
I'm implementing an invite type system, where the user can join a team with an invite code. This all works with the normal password flow (I added the invite code as an argument to the action) with a custom change to read the argument, but I'm not quite sure how to get that invite code through the various redirects for google/oauth flows, so it gets added to the google registration action as an argument.
Previously in other tools and languages I've passed state back and forth through as query params on the redirect_url or state. Is there any mechanism for that with the existing strategies? I want to support both invite code and no invite codes based on the registration url.
So far, I've been able to work around this by utilizing the secrets module for building up the
authorization_params. If I add a state keyword, then it gets forwarded to Assent (though that is deprecated) and passed through the flow. So far, that works for passing the state back and forth between redirects! I can pass the invite code back and forth in the state (though I think I'll also want to include a nonce, and Assent will verify it)....Ash.Policy.FilterCheck
Are we using this wrong? We have the following policy module:
```elixir
def describe(_opts), do: "Organization is one of the users orgs that they are an admin of"
...
Get user's role in given organization
Users belong to multiple organizations. In some orgs they are regular users and in others they are admins.
I need to add something to the User resource that takes an organization ID and returns the user's role in that organization. What would that thing be? A read action? A calculation?
There's an existing calculation called
organization_hierarchy that let's me get a list of organizations the user is a member of, e.g....Controlling tenancy when joining resources in queries
I have been working on a user-facing query builder in my application. I have a resource
Atlas.Tracking.Entity that I configured the multitenancy like so:
```elixir
multitenancy do
strategy :context...Solution:
ok so it looks like I goofed. it's mostly working as described. I might have changed multiple things:
...
Atlas.Tracking.Entity |> Ash.Query.for_read(:read, %{}, tenant: client) |> Atlas.QueryParser.add_to_query(query) |> Ash.read!()
Atlas.Tracking.Entity |> Ash.Query.for_read(:read, %{}, tenant: client) |> Atlas.QueryParser.add_to_query(query) |> Ash.read!()
Multitenancy plug
Hi. I am trying to create a multitenant system eith AshAuthentication and AshGraphql. However, I could not get actor put in context, so the tenant too. In my case single actor can have access to multiple tenants.
Let's assume there is a function get_selected_tenant(conn) and the User resource has_many Tenants (resource) with a role. I want to call PlugHelpers.put_tenant if the actor has any role in their selected tenant. Currently I could not even get the actor from conn (using :load_from_bearer plug, before my plug which will set the tenant)...
ash json api filters
```
question-filter-q_explanation{
contains [...]
eq [...]
greater_than [...]...
AshTrans update issue
This is for @Robert Timis.
I created a new project on ash HQ and added an attribute to user:
```
attribute :about_me, :string do
allow_nil? true...
Solution:
what the hell... now it works. 👺
sorry for bothering you. I don't understand what happened. 🙇
okay, maybe because I didn't create the user with embedded structs the update didn't work 🤔 might just be that.
again, sorry, my bad....
Complex Input Flattening - Action or Code Interface?
I have a create action that takes an argument (:member, a :map) which I call
change manage_relationship on a relationship, which then calls another instance of manage_relationship within that create action. This is all working beautifully, but it makes the API kind of gnarly, since I need to pass in a struct, which contains a struct, and then another struct within that, which really only have like 4 fields in total.
I was hoping to "flatten" the API a bit. I know there is a way to use custom_input to transform that when creating a code interface, but the examples in the docs are fairly simple (like going from artist to artist.id). I was able to get it to work this way, so functionality wise it works.
It feels weird to have this flattening logic defined with the code interface, is that the right way? I feel like this should process of going from a few args to a more complex arg should be in the action. I guess I can have a custom change action which calls Ash.Changeset.manage_relationship and builds the argument from there?...Bad join query when using attribute tenancy
Hi! I'm noticing a major performance bug when using attribute-based multi-tenancy in our app:
We have an a resource
Visit that has:
belongs_to :patient, Practices.Patient, public?: true
...Using struct data in filter expressions
I think I've tried to do this a few times and have never gotten it to work properly.
I have a calculation that takes a struct as an argument, and I want to use data from that struct in the expression, eg.
```elixir...
Solution:
instead of
^get_path(arg(:npc), :faction_id) it should be get_path(^arg(:npc), :faction_id)Confirmation Token Generated on Every Google Login
I'm using Ash Authentication + Google OAuth2 and I've noticed that every time I sign in with Google - even if I've already confirmed my account - a new
confirm_new_user token/email is generated. Here is my setup:
```elixir
authentication do
add_ons do
log_out_everywhere do...Solution:
which you can do by configuring it in the
auto_confirm_actions of the confirmation strategy listSpecify graphql interface
Is there a way to specify that the generated graphql object type for a resource implements a graphql interface?