Convenience functions for many_to_many relationships?

I'm trying to wrap my head around creating convenience functions for many_to_many relationships. Given the resources below, what I'd like to do is have an add_to_hub action in the User module that takes in a Hub record and creates a corresponding UsersToHubs record. How would I go about setting up that action, and is placing a function like this inside of my User resource module at all idiomatic for Ash? I cut off the TestApp.Hubs.Hub module due to character limit, but I set it up the same way as my User module
defmodule TestApp.Accounts.User do
use Ash.Resource, domain: TestApp.Accounts

actions do
defaults [:read]

create :create do
accept [:email, :first_name, :last_name]
end

create :add_to_hub do
#
# ?
#
end
end

attributes do
uuid_v7_primary_key :id

attribute :email, :string do
allow_nil? false
public? true
end
end

relationships do
many_to_many :hubs, TestApp.Hubs.Hub do
through TestApp.Hubs.UsersToHubs
source_attribute_on_join_resource :user_id
destination_attribute_on_join_resource :hub_id
end
end
end


defmodule TestApp.Hubs.UsersToHubs do
use Ash.Resource, domain: TestApp.Hubs

actions do
defaults [:read, :destroy, create: :*, update: :*]
end

attributes do
create_timestamp :inserted_at
update_timestamp :updated_at
end

relationships do
belongs_to :hub,
TestApp.Hubs.Hub,
primary_key?: true,
allow_nil?: false

belongs_to :user,
TestApp.Accounts.User,
primary_key?: true,
allow_nil?: false
end
end
defmodule TestApp.Accounts.User do
use Ash.Resource, domain: TestApp.Accounts

actions do
defaults [:read]

create :create do
accept [:email, :first_name, :last_name]
end

create :add_to_hub do
#
# ?
#
end
end

attributes do
uuid_v7_primary_key :id

attribute :email, :string do
allow_nil? false
public? true
end
end

relationships do
many_to_many :hubs, TestApp.Hubs.Hub do
through TestApp.Hubs.UsersToHubs
source_attribute_on_join_resource :user_id
destination_attribute_on_join_resource :hub_id
end
end
end


defmodule TestApp.Hubs.UsersToHubs do
use Ash.Resource, domain: TestApp.Hubs

actions do
defaults [:read, :destroy, create: :*, update: :*]
end

attributes do
create_timestamp :inserted_at
update_timestamp :updated_at
end

relationships do
belongs_to :hub,
TestApp.Hubs.Hub,
primary_key?: true,
allow_nil?: false

belongs_to :user,
TestApp.Accounts.User,
primary_key?: true,
allow_nil?: false
end
end
Solution:
I appreciate the very kind "read the manual" haha. Definitely overlooked the many_to_many example when I was reading the docs earlier. So it's basically just: ```elixir update :assign_to_hub do...
Jump to solution
2 Replies
ZachDaniel
ZachDaniel3mo ago
YOu should look into managing relationships and report back
Solution
tohsig
tohsig3mo ago
I appreciate the very kind "read the manual" haha. Definitely overlooked the many_to_many example when I was reading the docs earlier. So it's basically just:
update :assign_to_hub do
argument :hub_id, :uuid, allow_nil?: false
change manage_relationship(:hub_id, :hubs, type: :append)
end
update :assign_to_hub do
argument :hub_id, :uuid, allow_nil?: false
change manage_relationship(:hub_id, :hubs, type: :append)
end
Very cool.

Did you find this page helpful?