How to include a subquery fetch in an Update action

My goal is to create an update action on a parent resource that includes a “change manage_relationship” step to create a new related child item.

I know how to pass a map argument that can be used in that change, but…

How can I instead pass an id argument that is then used to look up a resource record in another resource type and use the results of that to craft the new child related item?

In SQL terms this would be an update with a nested select.

How to attack this in Ash? So far, my reading has not come up with any neat ways to achieve this.

Thanks
Martin

If I understand you correctly, you should be able to pass the id and ash will figure it out. An example from ash tests setup:

      update :update_with_reviewer do
        require_atomic? false
        argument :reviewer_id, :uuid, allow_nil?: true
        change manage_relationship(:reviewer_id, :reviewer, type: :append_and_remove)
        change {UpdateReviewFields, []}
      end

Although in docs it states.

The input provided to manage_relationship should be a map, in the case of to_one relationships, or a list of maps in the case of to_many relationships.

But AFAIS it is possible to just pass the uuid id. :thinking:

edit: think I misunderstood. :sweat_smile:

Depending on what you are trying to do, it may not be possible only with Ash. You can do things like this, which will happen in the same transaction:

change fn changeset, _ ->
  Ash.Changeset.before_action(changeset, fn changeset -> 
    data = look_some_stuff_up()
    Ash.Changeset.manage_relationship(changeset, :relationship, data)
  end)
end

But you can’t do it in a single query along the lines of an update w/ a nested select. You can do that with a manual action that uses Ecto, our lower level db interface.

The reason you can’t do it currently in a single query is that there is application logic that makes manage_relationship work, like authorizing the caller to read the records they want to relate, and applying policies etc.

1 Like

And (to be clear), the “look stuff up” can be regular functional use of Ash apis?

Yep! Absolutely.