diff --git a/app/models/note.rb b/app/models/note.rb index 7803a1c1deac6d01341999ab26bed65811bef39b..c24d47fc61f52393b34fbb6b96243ee06b7dfcc2 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -504,7 +504,15 @@ def bump_updated_at # Instead of calling touch which is throttled via ThrottledTouch concern, # we bump the updated_at column directly. This also prevents executing # after_commit callbacks that we don't need. - update_column(:updated_at, Time.current) + attributes_to_update = { updated_at: Time.current } + + # Notes that were edited before the `last_edited_at` column was added, fall back to `updated_at` for the edit time. + # We copy this over to the correct column so we don't erroneously change the edit timestamp. + if updated_by_id.present? && read_attribute(:last_edited_at).blank? + attributes_to_update[:last_edited_at] = updated_at + end + + update_columns(attributes_to_update) end def expire_etag_cache diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index da76c4975b43568fe74b3971c0f394e555df2813..b17cc659ff68f6f07d132cd3975b07793ea162ee 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -1685,4 +1685,27 @@ def expect_expiration(noteable) expect(note.commands_changes.keys).to contain_exactly(:emoji_award, :time_estimate, :spend_time) end end + + describe '#bump_updated_at', :freeze_time do + it 'sets updated_at to the current timestamp' do + note = create(:note, updated_at: 1.day.ago) + + note.bump_updated_at + note.reload + + expect(note.updated_at).to be_like_time(Time.current) + end + + context 'with legacy edited note' do + it 'copies updated_at to last_edited_at before bumping the timestamp' do + note = create(:note, updated_at: 1.day.ago, updated_by: create(:user), last_edited_at: nil) + + note.bump_updated_at + note.reload + + expect(note.last_edited_at).to be_like_time(1.day.ago) + expect(note.updated_at).to be_like_time(Time.current) + end + end + end end