Adding an association in an action based on argument

Hey, been a few minutes since I've done any work on an Ash project, hoping someone can jog my memory on how to accomplish something. Basically, I've got two resources, Maps.Map and Pin , where a Pin belongs to a Map. I want to pass an existing Map to the Pin as part of the create action. like so
# usage (via code interface)
Maps.Map.add_pin_to_map(some_map, attrs)
# usage (via code interface)
Maps.Map.add_pin_to_map(some_map, attrs)
Been searching the docs, but I can't really figure out how to take my argument and add the association
# maps/pin.ex
actions do
create :add_to_map do
argument :map, :struct,
allow_nil?: false,
constraints: [instance_of: Maps.Map]
end
end

relationships do
belongs_to :map, Maps.Map
end
# maps/pin.ex
actions do
create :add_to_map do
argument :map, :struct,
allow_nil?: false,
constraints: [instance_of: Maps.Map]
end
end

relationships do
belongs_to :map, Maps.Map
end
I was thinking it's something like using change like so, but not quite
# raises BadMapError
change set_attribute(:map_id, arg(:map).id)
# also raises BadMapError
change fn changeset, context ->
map = arg(:map)
Ash.Changeset.change_attribute(:map_id, map.id)
end
# raises BadMapError
change set_attribute(:map_id, arg(:map).id)
# also raises BadMapError
change fn changeset, context ->
map = arg(:map)
Ash.Changeset.change_attribute(:map_id, map.id)
end

Thanks!
4 Replies
kernel
kernel•5w ago
you should use manage_relationship 🙂 if you want to use the set_attribute directly, I think you need to uhh, set the attribute to be public?: true, and writeable?: true, it's recommended to use this instead https://hexdocs.pm/ash/relationships.html#managing-relationships
matt_savvy
matt_savvyOP•4w ago
I thought manage_relationship is for creating instances of the other relationship Like if I wanted to create one or more Pins by passing a list of them to the Map action Maybe I'm just approaching it from the wrong side Okay, I think I've got it
change manage_relationship(:map, :map, on_lookup: :relate)
change manage_relationship(:map, :map, on_lookup: :relate)
kernel
kernel•4w ago
yeah the type / on lookup things can be a bit confusing / annoying try type: :append_and_remove for existing thing
barnabasj
barnabasj•4w ago
This should also work.
change fn changeset, _ ->
Ash.Changeset.change_attribute(changeset, :map_id, Ash.Changeset.get_argument(changeset, :map).id)
end
change fn changeset, _ ->
Ash.Changeset.change_attribute(changeset, :map_id, Ash.Changeset.get_argument(changeset, :map).id)
end
the arg helper just returns {:__arg, :arg_name} which is then substituted by ash with the actual value, but .id doesn't work on that. manage_relationship is doing a bit more work for you, in cases where you need it and it also is useful for extenstions like ash_graphql, they check those to create a type for the :map argument for example

Did you find this page helpful?