fix: properly scope deletes to the records in question

fixes #29
This commit is contained in:
Zach Daniel 2024-05-06 11:32:27 -04:00
parent 843c0ff3b6
commit 033fb54691
2 changed files with 56 additions and 0 deletions

View file

@ -1359,6 +1359,7 @@ defmodule AshSqlite.DataLayer do
changeset.context
)
|> Ecto.Query.select(^select)
|> pkey_filter(changeset.data)
case AshSql.Atomics.query_with_atomics(
resource,
@ -1410,6 +1411,15 @@ defmodule AshSqlite.DataLayer do
end
end
defp pkey_filter(query, %resource{} = record) do
pkey =
record
|> Map.take(Ash.Resource.Info.primary_key(resource))
|> Map.to_list()
Ecto.Query.where(query, ^pkey)
end
@impl true
def destroy(resource, %{data: record} = changeset) do
ecto_changeset = ecto_changeset(record, changeset, :delete)

46
test/update_test.exs Normal file
View file

@ -0,0 +1,46 @@
defmodule AshSqlite.Test.UpdateTest do
use AshSqlite.RepoCase, async: false
alias AshSqlite.Test.Post
require Ash.Query
test "updating a record when multiple records are in the table will only update the desired record" do
# This test is here because of a previous bug in update that caused
# all records in the table to be updated.
id_1 = Ash.UUID.generate()
id_2 = Ash.UUID.generate()
new_post_1 =
Post
|> Ash.Changeset.for_create(:create, %{
id: id_1,
title: "new_post_1"
})
|> Ash.create!()
_new_post_2 =
Post
|> Ash.Changeset.for_create(:create, %{
id: id_2,
title: "new_post_2"
})
|> Ash.create!()
{:ok, updated_post_1} =
new_post_1
|> Ash.Changeset.for_update(:update, %{
title: "new_post_1_updated"
})
|> Ash.update()
# It is deliberate that post 2 is re-fetched from the db after the
# update to post 1. This ensure that post 2 was not updated.
post_2 = Ash.get!(Post, id_2)
assert updated_post_1.id == id_1
assert updated_post_1.title == "new_post_1_updated"
assert post_2.id == id_2
assert post_2.title == "new_post_2"
end
end