many_to_many in ash
defmodule Consola.Database.ShortUrl do
use Ash.Resource, domain: Consola.Database, data_layer: AshPostgres.DataLayer
postgres do
table "short_urls"
repo Consola.Repo
end
actions do
default_accept :*
defaults [:create, :read, :update, :destroy]
create :create_with_full_url do
default_accept [:related_full_urls, :short_url, :expires_at]
end
end
attributes do
uuid_primary_key :id
attribute :short_url, :string do
allow_nil? false
public? true
end
attribute :expires_at, :string do
allow_nil? false
public? true
end
create_timestamp :created_at
update_timestamp :updated_at
end
relationships do
many_to_many :related_full_urls, Consola.Database.FullUrl do
through Consola.Database.UrlMapping
public? true
writable? true
source_attribute :id
source_attribute_on_join_resource :short_url_id
destination_attribute :id
destination_attribute_on_join_resource :full_url_id
end
end
end
defmodule Consola.Database.ShortUrl do
use Ash.Resource, domain: Consola.Database, data_layer: AshPostgres.DataLayer
postgres do
table "short_urls"
repo Consola.Repo
end
actions do
default_accept :*
defaults [:create, :read, :update, :destroy]
create :create_with_full_url do
default_accept [:related_full_urls, :short_url, :expires_at]
end
end
attributes do
uuid_primary_key :id
attribute :short_url, :string do
allow_nil? false
public? true
end
attribute :expires_at, :string do
allow_nil? false
public? true
end
create_timestamp :created_at
update_timestamp :updated_at
end
relationships do
many_to_many :related_full_urls, Consola.Database.FullUrl do
through Consola.Database.UrlMapping
public? true
writable? true
source_attribute :id
source_attribute_on_join_resource :short_url_id
destination_attribute :id
destination_attribute_on_join_resource :full_url_id
end
end
end
params = %{
short_url: "https://shorturl-example-4.com",
expires_at: "2025-05-16T10:54:16Z",
related_full_urls: [%{url: "https://fullurl-example-4.com"}]
}
# to make this API work!
Consola.Database.ShortUrl|> Ash.Changeset.for_create(:create_with_full_url, params)|> Ash.create!()
params = %{
short_url: "https://shorturl-example-4.com",
expires_at: "2025-05-16T10:54:16Z",
related_full_urls: [%{url: "https://fullurl-example-4.com"}]
}
# to make this API work!
Consola.Database.ShortUrl|> Ash.Changeset.for_create(:create_with_full_url, params)|> Ash.create!()
writable? true
my understanding is that this should enable me to create the mapping (related_full_urls in the 'through' table) if I pass it as params.1 Reply
I guess I have to write
This did the trick!
manage_relationship
.
actions do
default_accept :*
defaults [:create, :read, :update, :destroy]
create :create_with_full_url do
default_accept [:short_url, :expires_at]
argument :related_full_urls, {:array, :map}, allow_nil?: true
change manage_relationship(:related_full_urls, type: :create)
end
end
actions do
default_accept :*
defaults [:create, :read, :update, :destroy]
create :create_with_full_url do
default_accept [:short_url, :expires_at]
argument :related_full_urls, {:array, :map}, allow_nil?: true
change manage_relationship(:related_full_urls, type: :create)
end
end