I’m trying to create a many_to_many relationship between User (Ash Authentication) and Group (or a team, etc) with a role. I’m looking to use this to track which users belong to which groups and to enforce policies.
I’ve created a join resource GroupMember with a role attribute and belongs_to relationships but for the life of me I can’t figure out manage_relationships with setting the :role on the join.
Anyone have an example I could learn from?
defmodule GroupMember do
attributes do
uuid_primary_key :id
attribute :role, :atom, constraints [one_of: [:admin, :moderator, :member]]
end
relationships do
belongs_to :group, Group
belongs_to :user, User
end
end
defmodule User do
...
relationships do
many_to_many :groups, Group do
through GroupMember
end
end
actions do
update :join_group do
require_atomic? false
argument :group_id, :uuid do
allow_nil? false
end
argument :role, Hestia.Accounts.Role do
allow_nil? false
default Hestia.Accounts.Role.default()
end
change manage_relationship(???)
end
end
...
end
Since you aren’t taking a :map argument, you’ll need to call Ash.Changeset.manage_relationship in a change yourself. Additionally, this can be made much simpler by managing the join relationship directly. It can be done when managing the many_to_many its just a bit more annoying.
Give the join relationship a better name. A has_many join relationship is always created, called <relationship_name>_join_assoc for many_to_many. It exists to make the underlying logic work, but is given an ugly name to encourage you to name it yourself if you want to use it for something. You don’t need to here, but this also allows you to define the join relationship has_many and customize its behavior if you need to.
many_to_many :groups, Group do
through GroupMember
join_relationship :group_members
end