Add extra attributes in Ash.Changeset.manage_relationship with many-to-many relationship

I have the following resource that links two other resources:

defmodule Core.Marketplace.Accounts.OrganizationReferredUser do
  @moduledoc false

  alias Core.Marketplace.Accounts

  use Ash.Resource,
    domain: Core.Marketplace.Accounts,
    data_layer: AshPostgres.DataLayer

  code_interface do
    define :read
    define :create
  end

  attributes do
    uuid_v7_primary_key :id

    attribute :metadata, :map do
      allow_nil? false
      default %{}
    end

    timestamps()
  end

  relationships do
    alias Accounts.{Organization, User}

    belongs_to :referred_user, User
    belongs_to :organization, Organization
  end

  postgres do
    table "organization_referred_users"

    references do
      reference :referred_user, on_update: :update, on_delete: :delete
      reference :organization, on_update: :update, on_delete: :delete
    end

    migration_defaults metadata: "%{}"

    repo Core.Repo
  end

  identities do
    identity :unique_association, [:referred_user_id, :organization_id]
  end

  actions do
    defaults [:read, :destroy]

    create :create do
      primary? true
      accept [:referred_user_id, :organization_id, :metadata]

      upsert? true
      upsert_fields []
      upsert_identity :unique_association
    end
  end
end

To add the resource, I use this in a change:

          Ash.Changeset.manage_relationship(
            changeset,
            :referred_organizations,
            [actor.organization_id],
            type: :append
          )

Now I wan’t to also set the metadata field when creating that relationship, but I can’t figure out how to add that param to the manage_relationship call.

          Ash.Changeset.manage_relationship(
            changeset,
            :referred_organizations,
            [%{organization_id: actor.organization_id, metadata: %{some: :metadata}}],
            type: :append, 
            join_fields: [:metadata]
          )

You should be able to do something like this to indicate that some inputs are passed to the join resource actions.

By join_fields do you meant join_keys?

It doesn’t seem like there is a join_fields option:

"** (Spark.Options.ValidationError) unknown options [:join_fields], valid options are: [:type, :authorize?, :eager_validate_with, :on_no_match, :value_is_key, :order_is_key, :identity_priority, :use_identities, :on_lookup, :on_match, :on_missing, :error_path, :join_keys, :meta, :ignore?]"

Using join_keys I get the following error:

{:error,
 %Ash.Error.Invalid{
   bread_crumbs: ["Error returned from: Core.Marketplace.Accounts.User.register_from_agent"],
   changeset: "#Changeset<>",
   errors: [
     %Ash.Error.Query.NotFound{
       primary_key: %{
         metadata: %{blibs: "blobs"},
         organization_id: "185e2073-baa8-48f7-ba7b-cc873104a528"
       },
       resource: Core.Marketplace.Accounts.Organization,
       splode: Ash.Error,
       bread_crumbs: ["Error returned from: Core.Marketplace.Accounts.User.register_from_agent"],
       vars: [],
       path: [:referred_organizations, 0],
       stacktrace: #Splode.Stacktrace<>,
       class: :invalid
     }
   ]
 }}

Ah, yeah typo on my part. I think perhaps you need id not organization_id

          Ash.Changeset.manage_relationship(
            changeset,
            :referred_organizations,
            [%{id: actor.organization_id, metadata: %{some: :metadata}}],
            type: :append, 
            join_keys: [:metadata]
          )

Oh, that was it, I didn’t realize that the id should be with the key id, thanks!