How do I insert an Item in Order?

I have the following resources:

defmodule App.Shop.Product do
  use Ash.Resource, data_layer: Ash.DataLayer.Ets

  attributes do
    uuid_primary_key :id
    attribute :name, :string
    attribute :price, :decimal
  end
end

defmodule App.Shop.Order do
  use Ash.Resource, data_layer: Ash.DataLayer.Ets

  attributes do
    uuid_primary_key :id
  end
  
  relationships do
    belongs_to :user, App.Shop.User do
      attribute_writable? true
    end
  end
end

defmodule App.Shop.OrderItem do
  use Ash.Resource, data_layer: Ash.DataLayer.Ets

  attributes do
    attribute :qty, :integer
  end

  relationships do 
    belongs_to :product, App.Shop.Product do
      primary_key? true
      allow_nil? false
    end

    belongs_to :order, App.Shop.Order do
      primary_key? true
      allow_nil? false
    end
  end
end

How do I insert product into Item, passing a value for qty, when creating a new order?

You’d want to add a many_to_many relationship and use the variation of manage_relationship that allows specifying join fields

create :create do
  argument :products, :map

  change manage_relationship(...., type: :create, on_no_match: {:create, :destination_action_name, :join_action_name, [:list, :of, :join_table, :params]}
end
1 Like

would it be this?

create :create do
  argument :items, {:array, :map}

  change manage_relationship(:items, :order_items, type: :append_and_remove)
end

items = [%{product_id: “f392ed6a-5f02-40c3-a762-77144d0c2d61”, qty: 2}, %{product_id: “f392ed6a-5f02-40c3-a762-77144d0c2d61"”, qty: 1}]

Ah yeah that will do everything but update the join table fields, but you’ll need to update the options to include the fields you want to update on the join table.

Take a look at the docs for Ash.Changeset.manage_relationship/4 to see the available options and what append_and_remove maps to.

2 Likes