dynamoid
dynamoid copied to clipboard
Conditional update array element
Hi, i'm using latest version (v 3.9.0) and I try to update element in array with condition. Here is example:
class Test
include Dynamoid::Document
table name: :test, key: :id, capacity_mode: :on_demand
field :test_array, :array, of: :string
end
Test.find(id).update(if: { 'test_array[0]': 'test' }) do |t|
t.set('test_array[0]': 'test_pass')
end
it doesn't work and ends with an error:
[Aws::DynamoDB::Client 400 0.211219 0 retries] update_item(table_name:"test",key:{"id"=>{s:"1"}},attribute_updates:{"updated_at"=>{action:"PUT",value:{s:"2023-09-25T07:19:01+00:00"}},"test_array[0]"=>{action:"PUT",value:{s:"test_pass"}}},expected:{"test_array[0]"=>{value:{s:"test"}}},return_values:"ALL_NEW") Aws::DynamoDB::Errors::ConditionalCheckFailedException The conditional request failed
I managed to achieve this using low-level methods
Dynamoid.adapter.client.update_item(
{
table_name: 'test',
key: {
"id": id
},
expression_attribute_values: {
":new_array_elem" => 'test_pass',
":prev_array_elem" => 'test',
},
condition_expression: "test_array[0] = :prev_array_elem",
update_expression: "SET test_array[0] = :new_array_elem",
return_values: "ALL_NEW"
}
)
And it works:
[Aws::DynamoDB::Client 200 0.158401 0 retries] update_item(table_name:"test",key:{"id"=>{s:"1"}},expression_attribute_values:{":new_array_elem"=>{s:"test_pass"},":prev_array_elem"=>{s:"test"}},condition_expression:"test_array[0] = :prev_array_elem",update_expression:"SET test_array[0] = :new_array_elem",return_values:"ALL_NEW")
it would be nice if it also worked from Dynamioid level. Or maybe i'm doing something wrong, so please provide working example ;) Thanks
Dynamoid doesn't support yet conditions on/updating of nested attributes or array elements.
But migration from deprecated attributes to the new expression-like ones (e.g. mentioned in the example above condition_expression
and update_expression
) is in progress. I've stated with #where
method (https://github.com/Dynamoid/dynamoid/pull/655) and hopefully will migrate all the public methods till the next release.