diff --git a/activerecord/lib/active_record/fixture_set/model_metadata.rb b/activerecord/lib/active_record/fixture_set/model_metadata.rb index fb23df6f45..5fb7824558 100644 --- a/activerecord/lib/active_record/fixture_set/model_metadata.rb +++ b/activerecord/lib/active_record/fixture_set/model_metadata.rb @@ -21,8 +21,7 @@ module ActiveRecord end def timestamp_column_names - @timestamp_column_names ||= - %w(created_at created_on updated_at updated_on) & @model_class.column_names + @model_class.all_timestamp_attributes_in_model end def inheritance_column_name diff --git a/activerecord/lib/active_record/integration.rb b/activerecord/lib/active_record/integration.rb index 4a97061731..b66cd94edc 100644 --- a/activerecord/lib/active_record/integration.rb +++ b/activerecord/lib/active_record/integration.rb @@ -97,17 +97,17 @@ module ActiveRecord def cache_version return unless cache_versioning - if has_attribute?("updated_at") + timestamp_column = self.class.attribute_aliases["updated_at"] || "updated_at" + + if has_attribute?(timestamp_column) timestamp = updated_at_before_type_cast if can_use_fast_cache_version?(timestamp) raw_timestamp_to_cache_version(timestamp) elsif timestamp = updated_at timestamp.utc.to_s(cache_timestamp_format) end - else - if self.class.has_attribute?("updated_at") - raise ActiveModel::MissingAttributeError, "missing attribute: updated_at" - end + elsif self.class.has_attribute?(timestamp_column) + raise ActiveModel::MissingAttributeError, "missing attribute: updated_at" end end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 943cc25a77..e06c347cc8 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -343,10 +343,13 @@ module ActiveRecord end def compute_cache_version(timestamp_column) # :nodoc: + timestamp_column = timestamp_column.to_s + timestamp_column = klass.attribute_aliases[timestamp_column] || timestamp_column + if loaded? || distinct_value size = records.size if size > 0 - timestamp = max_by(×tamp_column)._read_attribute(timestamp_column) + timestamp = records.map { |record| record._read_attribute(timestamp_column) }.max end else collection = eager_loading? ? apply_join_dependency : self diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb index c883d368b5..c9e6ef06b7 100644 --- a/activerecord/lib/active_record/timestamp.rb +++ b/activerecord/lib/active_record/timestamp.rb @@ -80,11 +80,11 @@ module ActiveRecord private def timestamp_attributes_for_create - ["created_at", "created_on"] + ["created_at", "created_on"].map! { |name| attribute_aliases[name] || name } end def timestamp_attributes_for_update - ["updated_at", "updated_on"] + ["updated_at", "updated_on"].map! { |name| attribute_aliases[name] || name } end def reload_schema_from_cache diff --git a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb index b7f213efc8..d44aaedbc1 100644 --- a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb +++ b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb @@ -55,10 +55,10 @@ class PostgresqlTimestampFixtureTest < ActiveRecord::PostgreSQLTestCase end def test_load_infinity_and_beyond - d = Developer.find_by_sql("select 'infinity'::timestamp as updated_at") + d = Developer.find_by_sql("select 'infinity'::timestamp as legacy_updated_at") assert d.first.updated_at.infinite?, "timestamp should be infinite" - d = Developer.find_by_sql("select '-infinity'::timestamp as updated_at") + d = Developer.find_by_sql("select '-infinity'::timestamp as legacy_updated_at") time = d.first.updated_at assert time.infinite?, "timestamp should be infinite" assert_operator time, :<, 0 diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 81bb38c4ad..2e5edfc2d8 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1106,8 +1106,8 @@ class BasicsTest < ActiveRecord::TestCase end def test_find_keeps_multiple_group_values - combined = Developer.all.merge!(group: "developers.name, developers.salary, developers.id, developers.created_at, developers.updated_at, developers.created_on, developers.updated_on").to_a - assert_equal combined, Developer.all.merge!(group: ["developers.name", "developers.salary", "developers.id", "developers.created_at", "developers.updated_at", "developers.created_on", "developers.updated_on"]).to_a + combined = Developer.merge(group: "developers.name, developers.salary, developers.id, developers.legacy_created_at, developers.legacy_updated_at, developers.legacy_created_on, developers.legacy_updated_on").to_a + assert_equal combined, Developer.merge(group: ["developers.name", "developers.salary", "developers.id", "developers.created_at", "developers.updated_at", "developers.created_on", "developers.updated_on"]).to_a end def test_find_symbol_ordered_last diff --git a/activerecord/test/cases/scoping/default_scoping_test.rb b/activerecord/test/cases/scoping/default_scoping_test.rb index e14ae8a6d4..5e9f97cb3a 100644 --- a/activerecord/test/cases/scoping/default_scoping_test.rb +++ b/activerecord/test/cases/scoping/default_scoping_test.rb @@ -166,10 +166,10 @@ class DefaultScopingTest < ActiveRecord::TestCase end def test_unscope_string_where_clauses_involved - dev_relation = Developer.order("salary DESC").where("created_at > ?", 1.year.ago) + dev_relation = Developer.order("salary DESC").where("legacy_created_at > ?", 1.year.ago) expected = dev_relation.collect(&:name) - dev_ordered_relation = DeveloperOrderedBySalary.where(name: "Jamis").where("created_at > ?", 1.year.ago) + dev_ordered_relation = DeveloperOrderedBySalary.where(name: "Jamis").where("legacy_created_at > ?", 1.year.ago) received = dev_ordered_relation.unscope(where: [:name]).collect(&:name) assert_equal expected.sort, received.sort diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb index 232e018e03..11e7d9f052 100644 --- a/activerecord/test/cases/timestamp_test.rb +++ b/activerecord/test/cases/timestamp_test.rb @@ -44,7 +44,7 @@ class TimestampTest < ActiveRecord::TestCase assert_predicate @developer, :changed?, "developer should be marked as changed" assert_equal ["salary"], @developer.changed assert_predicate @developer, :saved_changes? - assert_equal ["updated_at", "updated_on"], @developer.saved_changes.keys.sort + assert_equal ["legacy_updated_at", "legacy_updated_on"], @developer.saved_changes.keys.sort @developer.reload assert_equal previous_salary, @developer.salary @@ -57,7 +57,7 @@ class TimestampTest < ActiveRecord::TestCase assert_not_equal @previously_updated_at, developer.updated_at assert_not_predicate developer, :changed? assert_predicate developer, :saved_changes? - assert_equal ["updated_at", "updated_on"], developer.saved_changes.keys.sort + assert_equal ["legacy_updated_at", "legacy_updated_on"], developer.saved_changes.keys.sort developer.reload assert_not_equal @previously_updated_at, developer.updated_at diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb index 15428ca200..2a8fbe5e4e 100644 --- a/activerecord/test/models/developer.rb +++ b/activerecord/test/models/developer.rb @@ -3,6 +3,19 @@ require "ostruct" class Developer < ActiveRecord::Base + module TimestampAliases + extend ActiveSupport::Concern + + included do + alias_attribute :created_at, :legacy_created_at + alias_attribute :updated_at, :legacy_updated_at + alias_attribute :created_on, :legacy_created_on + alias_attribute :updated_on, :legacy_updated_on + end + end + + include TimestampAliases + module ProjectsAssociationExtension2 def find_least_recent order("id ASC").first @@ -193,6 +206,8 @@ class LazyBlockReferencingScopeDeveloperCalledDavid < ActiveRecord::Base end class DeveloperCalledJamis < ActiveRecord::Base + include Developer::TimestampAliases + self.table_name = "developers" default_scope { where(name: "Jamis") } @@ -280,6 +295,8 @@ class ThreadsafeDeveloper < ActiveRecord::Base end class CachedDeveloper < ActiveRecord::Base + include Developer::TimestampAliases + self.table_name = "developers" self.cache_timestamp_format = :number end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 1285881083..2437b74227 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -295,15 +295,15 @@ ActiveRecord::Schema.define do t.references :firm, index: false t.integer :mentor_id if supports_datetime_with_precision? - t.datetime :created_at, precision: 6 - t.datetime :updated_at, precision: 6 - t.datetime :created_on, precision: 6 - t.datetime :updated_on, precision: 6 + t.datetime :legacy_created_at, precision: 6 + t.datetime :legacy_updated_at, precision: 6 + t.datetime :legacy_created_on, precision: 6 + t.datetime :legacy_updated_on, precision: 6 else - t.datetime :created_at - t.datetime :updated_at - t.datetime :created_on - t.datetime :updated_on + t.datetime :legacy_created_at + t.datetime :legacy_updated_at + t.datetime :legacy_created_on + t.datetime :legacy_updated_on end end