AE
Ash Elixir•3y ago
Blibs

Which action to use to update/delete multiple rows at the same time?

I was wondering which action type should I use to update or delete multiple rows of a resource? For example, let's say I have a resource called Post, and I want to have an action where I update all posts from that user. At first glance, I would use the :update action for that. But it seems that both :create, :update and :destroy actions are only meant to run with only one resource/changeset at a time. So, if I would create an :update action, I would need to pass an empty changeset of a Post which doesn't mean anything to what I'm trying to do since inside the action I would ignore that changeset entirely, fetch all posts filtered by the actor id and update them. The action that makes more sense for that is :read since a :read action don't expect a changeset as an input. But, at the same time it seems wrong to use a :read action to update rows... So, in the end, what is the most idiomatic way to do something like this with Ash?
3 Replies
ZachDaniel
ZachDaniel•3y ago
At this point, a manual read action is the best way but I agree, that is not ideal I'm working on bulk actions no ETA yet but they are coming
Blibs
BlibsOP•3y ago
Ah, I see, I will do that for now then So, this is what I did, it works great, but I'm not sure how to make the action return the :ok since Ash expects a Enumerable
read :make_own_offers_old do
get? true

argument :property_id, :uuid, allow_nil?: false

filter expr(status == :open and offeror_id == ^actor(:id) and property_id == ^arg(:property_id))

manual fn _, query, _ ->
{_, _} = Marketplace.Repo.update_all(query, set: [status: :old])

{:ok, :ok}
end
end
read :make_own_offers_old do
get? true

argument :property_id, :uuid, allow_nil?: false

filter expr(status == :open and offeror_id == ^actor(:id) and property_id == ^arg(:property_id))

manual fn _, query, _ ->
{_, _} = Marketplace.Repo.update_all(query, set: [status: :old])

{:ok, :ok}
end
end
ZachDaniel
ZachDaniel•3y ago
🤔 You can't make it return :ok you'd need to do something like {:ok, []} once we have bulk actions, things will get much better on that front, but for now its a bit of a hack.

Did you find this page helpful?