From 499ab0408a93eff3ab4094c9a072298ebd545d24 Mon Sep 17 00:00:00 2001 From: Andrew Konchin Date: Sat, 9 Jul 2022 13:00:02 +0300 Subject: [PATCH 1/3] Specs: move specs for #load to a separate file --- spec/dynamoid/document_spec.rb | 35 ----------------------------- spec/dynamoid/loadable_spec.rb | 41 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 35 deletions(-) create mode 100644 spec/dynamoid/loadable_spec.rb diff --git a/spec/dynamoid/document_spec.rb b/spec/dynamoid/document_spec.rb index b0a95596..379adb1c 100644 --- a/spec/dynamoid/document_spec.rb +++ b/spec/dynamoid/document_spec.rb @@ -131,41 +131,6 @@ def city=(value) expect(address.errors.full_messages).to be_empty end - context '.reload' do - let(:address) { Address.create } - let(:message) { Message.create(text: 'Nice, supporting datetime range!', time: Time.now.to_datetime) } - let(:tweet) { tweet = Tweet.create(tweet_id: 'x', group: 'abc') } - - it 'reflects persisted changes' do - address.update_attributes(city: 'Chicago') - expect(address.reload.city).to eq 'Chicago' - end - - it 'uses a :consistent_read' do - expect(Tweet).to receive(:find).with(tweet.hash_key, range_key: tweet.range_value, consistent_read: true).and_return(tweet) - tweet.reload - end - - it 'works with range key' do - expect(tweet.reload.group).to eq 'abc' - end - - it 'uses dumped value of sort key to load document' do - klass = new_class do - range :activated_on, :date - field :name - end - - obj = klass.create!(activated_on: Date.today, name: 'Old value') - obj2 = klass.where(id: obj.id, activated_on: obj.activated_on).first - obj2.update_attributes(name: 'New value') - - expect { obj.reload }.to change { - obj.name - }.from('Old value').to('New value') - end - end - it 'has default table options' do address = Address.create diff --git a/spec/dynamoid/loadable_spec.rb b/spec/dynamoid/loadable_spec.rb new file mode 100644 index 00000000..3c26c3fd --- /dev/null +++ b/spec/dynamoid/loadable_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Dynamoid::Loadable do + + context '.reload' do + let(:address) { Address.create } + let(:message) { Message.create(text: 'Nice, supporting datetime range!', time: Time.now.to_datetime) } + let(:tweet) { tweet = Tweet.create(tweet_id: 'x', group: 'abc') } + + it 'reflects persisted changes' do + address.update_attributes(city: 'Chicago') + expect(address.reload.city).to eq 'Chicago' + end + + it 'uses a :consistent_read' do + expect(Tweet).to receive(:find).with(tweet.hash_key, range_key: tweet.range_value, consistent_read: true).and_return(tweet) + tweet.reload + end + + it 'works with range key' do + expect(tweet.reload.group).to eq 'abc' + end + + it 'uses dumped value of sort key to load document' do + klass = new_class do + range :activated_on, :date + field :name + end + + obj = klass.create!(activated_on: Date.today, name: 'Old value') + obj2 = klass.where(id: obj.id, activated_on: obj.activated_on).first + obj2.update_attributes(name: 'New value') + + expect { obj.reload }.to change { + obj.name + }.from('Old value').to('New value') + end + end +end From 98eb893681ded36c53f9a5c170b9018b44517768 Mon Sep 17 00:00:00 2001 From: Andrew Konchin Date: Sat, 9 Jul 2022 13:13:29 +0300 Subject: [PATCH 2/3] Spec: don't use predefined model classes in loadable_spec.rb --- spec/dynamoid/loadable_spec.rb | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/spec/dynamoid/loadable_spec.rb b/spec/dynamoid/loadable_spec.rb index 3c26c3fd..be9410b2 100644 --- a/spec/dynamoid/loadable_spec.rb +++ b/spec/dynamoid/loadable_spec.rb @@ -10,17 +10,36 @@ let(:tweet) { tweet = Tweet.create(tweet_id: 'x', group: 'abc') } it 'reflects persisted changes' do + klass = new_class do + field :city + end + + address = klass.create(city: 'Miami') + copy = klass.find(address.id) + address.update_attributes(city: 'Chicago') - expect(address.reload.city).to eq 'Chicago' + expect(copy.reload.city).to eq 'Chicago' end - it 'uses a :consistent_read' do - expect(Tweet).to receive(:find).with(tweet.hash_key, range_key: tweet.range_value, consistent_read: true).and_return(tweet) + it 'reads with strong consistency' do + klass = new_class do + field :message + end + + tweet = klass.create + + expect(klass).to receive(:find).with(tweet.id, consistent_read: true).and_return(tweet) tweet.reload end it 'works with range key' do - expect(tweet.reload.group).to eq 'abc' + klass = new_class do + field :message + range :group + end + + tweet = klass.create(group: 'tech') + expect(tweet.reload.group).to eq 'tech' end it 'uses dumped value of sort key to load document' do @@ -33,9 +52,7 @@ obj2 = klass.where(id: obj.id, activated_on: obj.activated_on).first obj2.update_attributes(name: 'New value') - expect { obj.reload }.to change { - obj.name - }.from('Old value').to('New value') + expect { obj.reload }.to change { obj.name }.from('Old value').to('New value') end end end From 340bb19a123e45786da4d0096b34496214b0901e Mon Sep 17 00:00:00 2001 From: Andrew Konchin Date: Sat, 9 Jul 2022 13:25:03 +0300 Subject: [PATCH 3/3] Fix #loadable - mark model as persisted --- CHANGELOG.md | 2 ++ lib/dynamoid/loadable.rb | 3 +++ spec/dynamoid/loadable_spec.rb | 13 +++++++++++++ 3 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7bc2f57..f940c72e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Fixed +* [#567](https://github.com/Dynamoid/dynamoid/pull/567) Fix `#reload` and mark reloaded model as persisted ### Added * [#536](https://github.com/Dynamoid/dynamoid/pull/536) Modernization * Support for Ruby 3.1 diff --git a/lib/dynamoid/loadable.rb b/lib/dynamoid/loadable.rb index 18191fbc..2310ed85 100644 --- a/lib/dynamoid/loadable.rb +++ b/lib/dynamoid/loadable.rb @@ -24,7 +24,10 @@ def reload end self.attributes = self.class.find(hash_key, **options).attributes + @associations.values.each(&:reset) + @new_record = false + self end end diff --git a/spec/dynamoid/loadable_spec.rb b/spec/dynamoid/loadable_spec.rb index be9410b2..efffca0b 100644 --- a/spec/dynamoid/loadable_spec.rb +++ b/spec/dynamoid/loadable_spec.rb @@ -54,5 +54,18 @@ expect { obj.reload }.to change { obj.name }.from('Old value').to('New value') end + + # https://github.com/Dynamoid/dynamoid/issues/564 + it 'marks model as persisted if not saved model is already persisted and successfuly reloaded' do + klass = new_class do + field :message + end + + object = klass.create(message: 'a') + copy = klass.new(id: object.id) + + expect { copy.reload }.to change { copy.new_record? }.from(true).to(false) + expect(copy.message).to eq 'a' + end end end