Hey guys
I am quite new to elixir and super fresh in ash.
I already have an app built with phoenix and wanted to use ash with it now. I already have all the auth i need thanks to the gen.auth
command. Everything works great and i got a poc working without ash.
Now i want to model my domains with ash and use the benefits it brings to the table.
I have a tenant resource that belongs to a user and this user is the owner. So i tried to model it according to the docs:
defmodule App.Tenant do
use Ash.Resource,
data_layer: AshPostgres.DataLayer
postgres do
table "tenants"
repo App.Repo
end
attributes do
uuid_primary_key :id
attribute :name, :string
end
relationships do
belongs_to :owner, App.Users.User
end
actions do
defaults [:read, :destroy, create: :*, update: :*]
end
end
But this of course does not work as the User is not a Spark DSL Entity/Resource…
Maybe a noob question and possibly i misread something in the docs, but i thought i do not have to use ash_auth and can still use the phoenix generated auth solution.
So how do i work with this?
- do i have to implement ash auth to make it work?
- do i have to extend the user module with some spark dsl sprinkle magic to make it work?
- can i define the relationship in another way? i mean it is basically a helper for creating a cross table, right?
Thanks in advance for any help
I am afraid you may have two options:
- Use Ash authentication (I recommend this).
- Create two different Repos. One for Ash another for the traditional Ecto.
If you go with the first option and your app has unit tests for protected route, you will have to also change the way you authenticate the user to the following
def login(conn, username \\ "test@example.com") do
{:ok, user} = create_user(username)
conn
|> Phoenix.ConnTest.init_test_session(%{})
|> put_session(:user, "user?id=#{user.id}")
end
1 Like
You can use the generated Phoenix auth in at least two ways:
- Refactor the Ecto schemas into Ash resources and the auth contexts to Ash actions.
- Duplicate the user Ecto schema as an Ash resource, and use that as the actor.
The actor in Ash is just a map, so you could just pass it the Ecto version of the user, but (I think) it will have a lot of limitations. For example, policies that leverage things like relates_to_actor_via
etc and other relationship-related things won’t work.
There is a not currently a way to sprinkle some magic onto an Ecto schema to turn it into an Ash resource, but it has been discussed in the past (actually, moreso the other way around, Ash → Ecto). But there are some tricky problems regarding doing that, so I think it’s not really planned at the moment.
1 Like
The relates_to_actor_via
should actually continue to work, because we just grab the appropriate destination attributes from the user. If you want to relate a resource to your “user”, it will have to be a User
. With that said, you can have an ecto schema for User
and an Ash.Resource
for User
just fine
1 Like
This sounds very promising. I will try that and will come back when i got it working. Thanks a lot!
1 Like
So far that seems to work! Now my app compiles and when registering users everything works fine
2 Likes