aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md4
-rw-r--r--activerecord/lib/active_record/associations/association.rb8
-rw-r--r--activerecord/lib/active_record/attribute_decorators.rb3
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb1
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb3
-rw-r--r--activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb7
-rw-r--r--activerecord/lib/active_record/attributes.rb3
-rw-r--r--activerecord/lib/active_record/autosave_association.rb9
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb10
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb15
-rw-r--r--activerecord/lib/active_record/connection_handling.rb2
-rw-r--r--activerecord/lib/active_record/enum.rb26
-rw-r--r--activerecord/lib/active_record/fixtures.rb20
-rw-r--r--activerecord/lib/active_record/inheritance.rb3
-rw-r--r--activerecord/lib/active_record/integration.rb6
-rw-r--r--activerecord/lib/active_record/locking/optimistic.rb3
-rw-r--r--activerecord/lib/active_record/model_schema.rb27
-rw-r--r--activerecord/lib/active_record/nested_attributes.rb3
-rw-r--r--activerecord/lib/active_record/readonly_attributes.rb3
-rw-r--r--activerecord/lib/active_record/reflection.rb6
-rw-r--r--activerecord/lib/active_record/relation.rb1
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb22
-rw-r--r--activerecord/lib/active_record/relation/delegation.rb2
-rw-r--r--activerecord/lib/active_record/scoping/default.rb7
-rw-r--r--activerecord/lib/active_record/scoping/named.rb12
-rw-r--r--activerecord/lib/active_record/timestamp.rb3
-rw-r--r--activerecord/lib/active_record/type/internal/abstract_json.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/connection_test.rb12
-rw-r--r--activerecord/test/cases/adapters/postgresql/uuid_test.rb10
-rw-r--r--activerecord/test/cases/associations/eager_test.rb6
-rw-r--r--activerecord/test/cases/calculations_test.rb12
-rw-r--r--activerecord/test/cases/connection_adapters/connection_handler_test.rb11
-rw-r--r--activerecord/test/cases/enum_test.rb4
-rw-r--r--activerecord/test/cases/json_shared_test_cases.rb11
-rw-r--r--activerecord/test/cases/migration/command_recorder_test.rb5
-rw-r--r--activerecord/test/cases/migration/rename_table_test.rb23
-rw-r--r--activerecord/test/cases/relation/merging_test.rb2
-rw-r--r--activerecord/test/cases/validations_test.rb14
-rw-r--r--activerecord/test/fixtures/books.yml1
-rw-r--r--activerecord/test/models/book.rb2
-rw-r--r--activerecord/test/models/category.rb9
-rw-r--r--activerecord/test/models/topic.rb2
44 files changed, 196 insertions, 151 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index d17bbf80ca..1f8163db12 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Deprecate passing arguments and block at the same time to `count` and `sum` in `ActiveRecord::Calculations`.
+
+ *Ryuta Kamizono*
+
* Loading model schema from database is now thread-safe.
Fixes #28589.
diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb
index 0f330af2f6..ee2e79889f 100644
--- a/activerecord/lib/active_record/associations/association.rb
+++ b/activerecord/lib/active_record/associations/association.rb
@@ -162,14 +162,6 @@ module ActiveRecord
reset
end
- def interpolate(sql, record = nil)
- if sql.respond_to?(:to_proc)
- owner.instance_exec(record, &sql)
- else
- sql
- end
- end
-
# We can't dump @reflection since it contains the scope proc
def marshal_dump
ivars = (instance_variables - [:@reflection]).map { |name| [name, instance_variable_get(name)] }
diff --git a/activerecord/lib/active_record/attribute_decorators.rb b/activerecord/lib/active_record/attribute_decorators.rb
index c39e9ce4c5..5bc8527745 100644
--- a/activerecord/lib/active_record/attribute_decorators.rb
+++ b/activerecord/lib/active_record/attribute_decorators.rb
@@ -3,8 +3,7 @@ module ActiveRecord
extend ActiveSupport::Concern
included do
- class_attribute :attribute_type_decorations, instance_accessor: false # :internal:
- self.attribute_type_decorations = TypeDecorator.new
+ class_attribute :attribute_type_decorations, instance_accessor: false, default: TypeDecorator.new # :internal:
end
module ClassMethods # :nodoc:
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index ebe06566cc..83c61fad19 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -62,7 +62,6 @@ module ActiveRecord
super(attribute_names)
@attribute_methods_generated = true
end
- true
end
def undefine_attribute_methods # :nodoc:
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index bd5003d63a..76987fb8f4 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -14,8 +14,7 @@ module ActiveRecord
raise "You cannot include Dirty after Timestamp"
end
- class_attribute :partial_writes, instance_writer: false
- self.partial_writes = true
+ class_attribute :partial_writes, instance_writer: false, default: true
after_create { changes_internally_applied }
after_update { changes_internally_applied }
diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
index 321d039ed4..4a8d231503 100644
--- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
+++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
@@ -57,11 +57,8 @@ module ActiveRecord
mattr_accessor :time_zone_aware_attributes, instance_writer: false
self.time_zone_aware_attributes = false
- class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false
- self.skip_time_zone_conversion_for_attributes = []
-
- class_attribute :time_zone_aware_types, instance_writer: false
- self.time_zone_aware_types = [:datetime, :time]
+ class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false, default: []
+ class_attribute :time_zone_aware_types, instance_writer: false, default: [ :datetime, :time ]
end
module ClassMethods
diff --git a/activerecord/lib/active_record/attributes.rb b/activerecord/lib/active_record/attributes.rb
index 75f5ba3a96..475b9beec4 100644
--- a/activerecord/lib/active_record/attributes.rb
+++ b/activerecord/lib/active_record/attributes.rb
@@ -6,8 +6,7 @@ module ActiveRecord
extend ActiveSupport::Concern
included do
- class_attribute :attributes_to_define_after_schema_loads, instance_accessor: false # :internal:
- self.attributes_to_define_after_schema_loads = {}
+ class_attribute :attributes_to_define_after_schema_loads, instance_accessor: false, default: {} # :internal:
end
module ClassMethods
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index ebe92e7878..829a4f6e86 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -216,13 +216,7 @@ module ActiveRecord
method = :validate_single_association
end
- define_non_cyclic_method(validation_method) do
- send(method, reflection)
- # TODO: remove the following line as soon as the return value of
- # callbacks is ignored, that is, returning `false` does not
- # display a deprecation warning or halts the callback chain.
- true
- end
+ define_non_cyclic_method(validation_method) { send(method, reflection) }
validate validation_method
after_validation :_ensure_no_duplicate_errors
end
@@ -369,7 +363,6 @@ module ActiveRecord
# association whether or not the parent was a new record before saving.
def before_save_collection_association
@new_record_before_save = new_record?
- true
end
def after_save_collection_association
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index abc15f595f..01599985ca 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -29,8 +29,7 @@ module ActiveRecord
# to your application.rb file:
#
# ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans = false
- class_attribute :emulate_booleans
- self.emulate_booleans = true
+ class_attribute :emulate_booleans, default: true
NATIVE_DATABASE_TYPES = {
primary_key: "bigint auto_increment PRIMARY KEY",
@@ -839,11 +838,6 @@ module ActiveRecord
end
class MysqlJson < Type::Internal::AbstractJson # :nodoc:
- def changed_in_place?(raw_old_value, new_value)
- # Normalization is required because MySQL JSON data format includes
- # the space between the elements.
- super(serialize(deserialize(raw_old_value)), new_value)
- end
end
class MysqlString < Type::String # :nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
index 87391b5dc7..705cb7f0b3 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
@@ -6,16 +6,6 @@ module ActiveRecord
def type
:jsonb
end
-
- def changed_in_place?(raw_old_value, new_value)
- # Postgres does not preserve insignificant whitespaces when
- # round-tripping jsonb columns. This causes some false positives for
- # the comparison here. Therefore, we need to parse and re-dump the
- # raw value here to ensure the insignificant whitespaces are
- # consistent with our encoder's output.
- raw_old_value = serialize(deserialize(raw_old_value))
- super(raw_old_value, new_value)
- end
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
index da8d0c6992..44eb666965 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
@@ -62,7 +62,7 @@ module ActiveRecord
def quote_default_expression(value, column) # :nodoc:
if value.is_a?(Proc)
value.call
- elsif column.type == :uuid && value.include?("()")
+ elsif column.type == :uuid && /\(\)/.match?(value)
value # Does not quote function default values for UUID columns
elsif column.respond_to?(:array?)
value = type_cast_from_column(column, value)
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
index 5b483ad4ab..55566f1e34 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -186,17 +186,17 @@ module ActiveRecord
# Returns the current database encoding format.
def encoding
- select_value("SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname LIKE '#{current_database}'", "SCHEMA")
+ select_value("SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = current_database()", "SCHEMA")
end
# Returns the current database collation.
def collation
- select_value("SELECT datcollate FROM pg_database WHERE datname LIKE '#{current_database}'", "SCHEMA")
+ select_value("SELECT datcollate FROM pg_database WHERE datname = current_database()", "SCHEMA")
end
# Returns the current database ctype.
def ctype
- select_value("SELECT datctype FROM pg_database WHERE datname LIKE '#{current_database}'", "SCHEMA")
+ select_value("SELECT datctype FROM pg_database WHERE datname = current_database()", "SCHEMA")
end
# Returns an array of schema names.
@@ -377,14 +377,15 @@ module ActiveRecord
clear_cache!
execute "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
pk, seq = pk_and_sequence_for(new_name)
- if seq && seq.identifier == "#{table_name}_#{pk}_seq"
- new_seq = "#{new_name}_#{pk}_seq"
+ if pk
idx = "#{table_name}_pkey"
new_idx = "#{new_name}_pkey"
- execute "ALTER TABLE #{seq.quoted} RENAME TO #{quote_table_name(new_seq)}"
execute "ALTER INDEX #{quote_table_name(idx)} RENAME TO #{quote_table_name(new_idx)}"
+ if seq && seq.identifier == "#{table_name}_#{pk}_seq"
+ new_seq = "#{new_name}_#{pk}_seq"
+ execute "ALTER TABLE #{seq.quoted} RENAME TO #{quote_table_name(new_seq)}"
+ end
end
-
rename_table_indexes(table_name, new_name)
end
diff --git a/activerecord/lib/active_record/connection_handling.rb b/activerecord/lib/active_record/connection_handling.rb
index 2ede92feff..b8fbb489b6 100644
--- a/activerecord/lib/active_record/connection_handling.rb
+++ b/activerecord/lib/active_record/connection_handling.rb
@@ -1,6 +1,6 @@
module ActiveRecord
module ConnectionHandling
- RAILS_ENV = -> { (Rails.env if defined?(Rails.env)) || ENV["RAILS_ENV"] || ENV["RACK_ENV"] }
+ RAILS_ENV = -> { (Rails.env if defined?(Rails.env)) || ENV["RAILS_ENV"].presence || ENV["RACK_ENV"].presence }
DEFAULT_ENV = -> { RAILS_ENV.call || "default_env" }
# Establishes the connection to the database. Accepts a hash as input where
diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb
index 0ab03b2ab3..12ef58a941 100644
--- a/activerecord/lib/active_record/enum.rb
+++ b/activerecord/lib/active_record/enum.rb
@@ -95,8 +95,7 @@ module ActiveRecord
module Enum
def self.extended(base) # :nodoc:
- base.class_attribute(:defined_enums, instance_writer: false)
- base.defined_enums = {}
+ base.class_attribute(:defined_enums, instance_writer: false, default: {})
end
def inherited(base) # :nodoc:
@@ -154,11 +153,12 @@ module ActiveRecord
definitions.each do |name, values|
# statuses = { }
enum_values = ActiveSupport::HashWithIndifferentAccess.new
- name = name.to_sym
+ name = name.to_s
# def self.statuses() statuses end
- detect_enum_conflict!(name, name.to_s.pluralize, true)
- klass.singleton_class.send(:define_method, name.to_s.pluralize) { enum_values }
+ detect_enum_conflict!(name, name.pluralize, true)
+ singleton_class.send(:define_method, name.pluralize) { enum_values }
+ defined_enums[name] = enum_values
detect_enum_conflict!(name, name)
detect_enum_conflict!(name, "#{name}=")
@@ -170,7 +170,7 @@ module ActiveRecord
_enum_methods_module.module_eval do
pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
- pairs.each do |value, i|
+ pairs.each do |label, value|
if enum_prefix == true
prefix = "#{name}_"
elsif enum_prefix
@@ -182,23 +182,23 @@ module ActiveRecord
suffix = "_#{enum_suffix}"
end
- value_method_name = "#{prefix}#{value}#{suffix}"
- enum_values[value] = i
+ value_method_name = "#{prefix}#{label}#{suffix}"
+ enum_values[label] = value
+ label = label.to_s
- # def active?() status == 0 end
+ # def active?() status == "active" end
klass.send(:detect_enum_conflict!, name, "#{value_method_name}?")
- define_method("#{value_method_name}?") { self[attr] == value.to_s }
+ define_method("#{value_method_name}?") { self[attr] == label }
- # def active!() update! status: :active end
+ # def active!() update!(status: 0) end
klass.send(:detect_enum_conflict!, name, "#{value_method_name}!")
define_method("#{value_method_name}!") { update!(attr => value) }
- # scope :active, -> { where status: 0 }
+ # scope :active, -> { where(status: 0) }
klass.send(:detect_enum_conflict!, name, value_method_name, true)
klass.scope value_method_name, -> { where(attr => value) }
end
end
- defined_enums[name.to_s] = enum_values
end
end
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index c19216702c..bad6542be2 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -878,20 +878,12 @@ module ActiveRecord
included do
class_attribute :fixture_path, instance_writer: false
- class_attribute :fixture_table_names
- class_attribute :fixture_class_names
- class_attribute :use_transactional_tests
- class_attribute :use_instantiated_fixtures # true, false, or :no_instances
- class_attribute :pre_loaded_fixtures
- class_attribute :config
-
- self.fixture_table_names = []
- self.use_instantiated_fixtures = false
- self.pre_loaded_fixtures = false
- self.config = ActiveRecord::Base
-
- self.fixture_class_names = {}
- self.use_transactional_tests = true
+ class_attribute :fixture_table_names, default: []
+ class_attribute :fixture_class_names, default: {}
+ class_attribute :use_transactional_tests, default: true
+ class_attribute :use_instantiated_fixtures, default: false # true, false, or :no_instances
+ class_attribute :pre_loaded_fixtures, default: false
+ class_attribute :config, default: ActiveRecord::Base
end
module ClassMethods
diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb
index 236a65eba7..5776807507 100644
--- a/activerecord/lib/active_record/inheritance.rb
+++ b/activerecord/lib/active_record/inheritance.rb
@@ -38,8 +38,7 @@ module ActiveRecord
included do
# Determines whether to store the full constant name including namespace when using STI.
# This is true, by default.
- class_attribute :store_full_sti_class, instance_writer: false
- self.store_full_sti_class = true
+ class_attribute :store_full_sti_class, instance_writer: false, default: true
end
module ClassMethods
diff --git a/activerecord/lib/active_record/integration.rb b/activerecord/lib/active_record/integration.rb
index 32362fa86f..cf954852bc 100644
--- a/activerecord/lib/active_record/integration.rb
+++ b/activerecord/lib/active_record/integration.rb
@@ -11,8 +11,7 @@ module ActiveRecord
# versioning is off. Accepts any of the symbols in <tt>Time::DATE_FORMATS</tt>.
#
# This is +:usec+, by default.
- class_attribute :cache_timestamp_format, instance_writer: false
- self.cache_timestamp_format = :usec
+ class_attribute :cache_timestamp_format, instance_writer: false, default: :usec
##
# :singleton-method:
@@ -20,8 +19,7 @@ module ActiveRecord
# by a changing version in the #cache_version method.
#
# This is +false+, by default until Rails 6.0.
- class_attribute :cache_versioning, instance_writer: false
- self.cache_versioning = false
+ class_attribute :cache_versioning, instance_writer: false, default: false
end
# Returns a +String+, which Action Pack uses for constructing a URL to this
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index 78ce9f8291..3c7110369b 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -51,8 +51,7 @@ module ActiveRecord
extend ActiveSupport::Concern
included do
- class_attribute :lock_optimistically, instance_writer: false
- self.lock_optimistically = true
+ class_attribute :lock_optimistically, instance_writer: false, default: true
end
def locking_enabled? #:nodoc:
diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb
index 013562708c..1179a60e9b 100644
--- a/activerecord/lib/active_record/model_schema.rb
+++ b/activerecord/lib/active_record/model_schema.rb
@@ -130,26 +130,13 @@ module ActiveRecord
included do
mattr_accessor :primary_key_prefix_type, instance_writer: false
- class_attribute :table_name_prefix, instance_writer: false
- self.table_name_prefix = ""
-
- class_attribute :table_name_suffix, instance_writer: false
- self.table_name_suffix = ""
-
- class_attribute :schema_migrations_table_name, instance_accessor: false
- self.schema_migrations_table_name = "schema_migrations"
-
- class_attribute :internal_metadata_table_name, instance_accessor: false
- self.internal_metadata_table_name = "ar_internal_metadata"
-
- class_attribute :protected_environments, instance_accessor: false
- self.protected_environments = ["production"]
-
- class_attribute :pluralize_table_names, instance_writer: false
- self.pluralize_table_names = true
-
- class_attribute :ignored_columns, instance_accessor: false
- self.ignored_columns = [].freeze
+ class_attribute :table_name_prefix, instance_writer: false, default: ""
+ class_attribute :table_name_suffix, instance_writer: false, default: ""
+ class_attribute :schema_migrations_table_name, instance_accessor: false, default: "schema_migrations"
+ class_attribute :internal_metadata_table_name, instance_accessor: false, default: "ar_internal_metadata"
+ class_attribute :protected_environments, instance_accessor: false, default: [ "production" ]
+ class_attribute :pluralize_table_names, instance_writer: false, default: true
+ class_attribute :ignored_columns, instance_accessor: false, default: [].freeze
self.inheritance_column = "type"
diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index 3f39fb84e8..917bc76993 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -10,8 +10,7 @@ module ActiveRecord
extend ActiveSupport::Concern
included do
- class_attribute :nested_attributes_options, instance_writer: false
- self.nested_attributes_options = {}
+ class_attribute :nested_attributes_options, instance_writer: false, default: {}
end
# = Active Record Nested Attributes
diff --git a/activerecord/lib/active_record/readonly_attributes.rb b/activerecord/lib/active_record/readonly_attributes.rb
index 6274996ab8..af6473d250 100644
--- a/activerecord/lib/active_record/readonly_attributes.rb
+++ b/activerecord/lib/active_record/readonly_attributes.rb
@@ -3,8 +3,7 @@ module ActiveRecord
extend ActiveSupport::Concern
included do
- class_attribute :_attr_readonly, instance_accessor: false
- self._attr_readonly = []
+ class_attribute :_attr_readonly, instance_accessor: false, default: []
end
module ClassMethods
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 0bfd59d7bd..429f9a257a 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -8,10 +8,8 @@ module ActiveRecord
extend ActiveSupport::Concern
included do
- class_attribute :_reflections, instance_writer: false
- class_attribute :aggregate_reflections, instance_writer: false
- self._reflections = {}
- self.aggregate_reflections = {}
+ class_attribute :_reflections, instance_writer: false, default: {}
+ class_attribute :aggregate_reflections, instance_writer: false, default: {}
end
def self.create(macro, name, scope, options, ar)
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 86b77a7cec..7a8f9abb36 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -18,6 +18,7 @@ module ActiveRecord
attr_reader :table, :klass, :loaded, :predicate_builder
alias :model :klass
alias :loaded? :loaded
+ alias :locked? :locked
def initialize(klass, table, predicate_builder, values = {})
@klass = klass
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index 861b2125d4..c562f214c9 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -37,7 +37,16 @@ module ActiveRecord
# Note: not all valid {Relation#select}[rdoc-ref:QueryMethods#select] expressions are valid #count expressions. The specifics differ
# between databases. In invalid cases, an error from the database is thrown.
def count(column_name = nil)
- return super() if block_given?
+ if block_given?
+ unless column_name.nil?
+ ActiveSupport::Deprecation.warn \
+ "When `count' is called with a block, it ignores other arguments. " \
+ "This behavior is now deprecated and will result in an ArgumentError in Rails 5.3."
+ end
+
+ return super()
+ end
+
calculate(:count, column_name)
end
@@ -73,7 +82,16 @@ module ActiveRecord
#
# Person.sum(:age) # => 4562
def sum(column_name = nil)
- return super() if block_given?
+ if block_given?
+ unless column_name.nil?
+ ActiveSupport::Deprecation.warn \
+ "When `sum' is called with a block, it ignores other arguments. " \
+ "This behavior is now deprecated and will result in an ArgumentError in Rails 5.3."
+ end
+
+ return super()
+ end
+
calculate(:sum, column_name)
end
diff --git a/activerecord/lib/active_record/relation/delegation.rb b/activerecord/lib/active_record/relation/delegation.rb
index 8b4dd25689..dada0fddf8 100644
--- a/activerecord/lib/active_record/relation/delegation.rb
+++ b/activerecord/lib/active_record/relation/delegation.rb
@@ -44,6 +44,8 @@ module ActiveRecord
delegate :table_name, :quoted_table_name, :primary_key, :quoted_primary_key,
:connection, :columns_hash, to: :klass
+ delegate :ast, :locked, to: :arel
+
module ClassSpecificRelation # :nodoc:
extend ActiveSupport::Concern
diff --git a/activerecord/lib/active_record/scoping/default.rb b/activerecord/lib/active_record/scoping/default.rb
index 2daa48859a..ba5cc29ac1 100644
--- a/activerecord/lib/active_record/scoping/default.rb
+++ b/activerecord/lib/active_record/scoping/default.rb
@@ -5,11 +5,8 @@ module ActiveRecord
included do
# Stores the default scope for the class.
- class_attribute :default_scopes, instance_writer: false, instance_predicate: false
- class_attribute :default_scope_override, instance_writer: false, instance_predicate: false
-
- self.default_scopes = []
- self.default_scope_override = nil
+ class_attribute :default_scopes, instance_writer: false, instance_predicate: false, default: []
+ class_attribute :default_scope_override, instance_writer: false, instance_predicate: false, default: nil
end
module ClassMethods
diff --git a/activerecord/lib/active_record/scoping/named.rb b/activerecord/lib/active_record/scoping/named.rb
index 93c6f1d87e..a61fdd6454 100644
--- a/activerecord/lib/active_record/scoping/named.rb
+++ b/activerecord/lib/active_record/scoping/named.rb
@@ -159,17 +159,17 @@ module ActiveRecord
if body.respond_to?(:to_proc)
singleton_class.send(:define_method, name) do |*args|
- scope = all.scoping { instance_exec(*args, &body) }
+ scope = all
+ scope = scope.scoping { instance_exec(*args, &body) || scope }
scope = scope.extending(extension) if extension
-
- scope || all
+ scope
end
else
singleton_class.send(:define_method, name) do |*args|
- scope = all.scoping { body.call(*args) }
+ scope = all
+ scope = scope.scoping { body.call(*args) || scope }
scope = scope.extending(extension) if extension
-
- scope || all
+ scope
end
end
end
diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb
index 09d8d1cdd4..55f3a194a9 100644
--- a/activerecord/lib/active_record/timestamp.rb
+++ b/activerecord/lib/active_record/timestamp.rb
@@ -43,8 +43,7 @@ module ActiveRecord
extend ActiveSupport::Concern
included do
- class_attribute :record_timestamps
- self.record_timestamps = true
+ class_attribute :record_timestamps, default: true
end
def initialize_dup(other) # :nodoc:
diff --git a/activerecord/lib/active_record/type/internal/abstract_json.rb b/activerecord/lib/active_record/type/internal/abstract_json.rb
index e19c5a14da..a8d6a63465 100644
--- a/activerecord/lib/active_record/type/internal/abstract_json.rb
+++ b/activerecord/lib/active_record/type/internal/abstract_json.rb
@@ -24,6 +24,10 @@ module ActiveRecord
end
end
+ def changed_in_place?(raw_old_value, new_value)
+ deserialize(raw_old_value) != new_value
+ end
+
def accessor
ActiveRecord::Store::StringKeyedHashAccessor
end
diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb
index 3deb007513..32afe331fa 100644
--- a/activerecord/test/cases/adapters/postgresql/connection_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb
@@ -31,15 +31,21 @@ module ActiveRecord
end
def test_encoding
- assert_not_nil @connection.encoding
+ assert_queries(1) do
+ assert_not_nil @connection.encoding
+ end
end
def test_collation
- assert_not_nil @connection.collation
+ assert_queries(1) do
+ assert_not_nil @connection.collation
+ end
end
def test_ctype
- assert_not_nil @connection.ctype
+ assert_queries(1) do
+ assert_not_nil @connection.ctype
+ end
end
def test_default_client_min_messages
diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb
index 52e4a38cae..6ebe9d82a7 100644
--- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb
@@ -63,6 +63,16 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
UUIDType.reset_column_information
end
+ def test_add_column_with_null_true_and_default_nil
+ assert_nothing_raised do
+ connection.add_column :uuid_data_type, :thingy, :uuid, null: true, default: nil
+ end
+ UUIDType.reset_column_information
+ column = UUIDType.columns_hash["thingy"]
+ assert column.null
+ assert_nil column.default
+ end
+
def test_data_type_of_uuid_types
column = UUIDType.columns_hash["guid"]
assert_equal :uuid, column.type
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 36238dd088..4271a09c9b 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -1094,12 +1094,6 @@ class EagerAssociationTest < ActiveRecord::TestCase
assert_equal authors(:david), assert_no_queries { posts[0].author }
posts = assert_queries(2) do
- Post.all.merge!(select: "distinct posts.*", includes: :author, joins: [:comments], where: "comments.body like 'Thank you%'", order: "posts.id").to_a
- end
- assert_equal [posts(:welcome)], posts
- assert_equal authors(:david), assert_no_queries { posts[0].author }
-
- posts = assert_queries(2) do
Post.all.merge!(includes: :author, joins: { taggings: :tag }, where: "tags.name = 'General'", order: "posts.id").to_a
end
assert_equal posts(:welcome, :thinking), posts
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index 3214d778d4..93f8ab18c2 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -809,4 +809,16 @@ class CalculationsTest < ActiveRecord::TestCase
def test_group_by_attribute_with_custom_type
assert_equal({ "proposed" => 2, "published" => 2 }, Book.group(:status).count)
end
+
+ def test_deprecate_count_with_block_and_column_name
+ assert_deprecated do
+ assert_equal 6, Account.count(:firm_id) { true }
+ end
+ end
+
+ def test_deprecate_sum_with_block_and_column_name
+ assert_deprecated do
+ assert_equal 6, Account.sum(:firm_id) { 1 }
+ end
+ end
end
diff --git a/activerecord/test/cases/connection_adapters/connection_handler_test.rb b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
index 681399c8bb..2a71f08d90 100644
--- a/activerecord/test/cases/connection_adapters/connection_handler_test.rb
+++ b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
@@ -9,6 +9,17 @@ module ActiveRecord
@pool = @handler.establish_connection(ActiveRecord::Base.configurations["arunit"])
end
+ def test_default_env_fall_back_to_default_env_when_rails_env_or_rack_env_is_empty_string
+ original_rails_env = ENV["RAILS_ENV"]
+ original_rack_env = ENV["RACK_ENV"]
+ ENV["RAILS_ENV"] = ENV["RACK_ENV"] = ""
+
+ assert_equal "default_env", ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
+ ensure
+ ENV["RAILS_ENV"] = original_rails_env
+ ENV["RACK_ENV"] = original_rack_env
+ end
+
def test_establish_connection_uses_spec_name
config = { "readonly" => { "adapter" => "sqlite3" } }
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new(config)
diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb
index 7f63bb2473..db3da53487 100644
--- a/activerecord/test/cases/enum_test.rb
+++ b/activerecord/test/cases/enum_test.rb
@@ -6,7 +6,6 @@ class EnumTest < ActiveRecord::TestCase
fixtures :books, :authors
setup do
- @author = authors(:david)
@book = books(:awdr)
end
@@ -39,6 +38,8 @@ class EnumTest < ActiveRecord::TestCase
assert_equal @book, Book.author_visibility_visible.first
assert_equal @book, Book.illustrator_visibility_visible.first
assert_equal @book, Book.medium_to_read.first
+ assert_equal books(:ddd), Book.forgotten.first
+ assert_equal books(:rfr), authors(:david).unpublished_books.first
end
test "find via where with values" do
@@ -57,7 +58,6 @@ class EnumTest < ActiveRecord::TestCase
assert_not_equal @book, Book.where(status: :written).first
assert_equal @book, Book.where(status: [:published]).first
assert_not_equal @book, Book.where(status: [:written]).first
- assert_not @author.unpublished_books.include?(@book)
assert_not_equal @book, Book.where.not(status: :published).first
assert_equal @book, Book.where.not(status: :written).first
end
diff --git a/activerecord/test/cases/json_shared_test_cases.rb b/activerecord/test/cases/json_shared_test_cases.rb
index d190b027bf..ef5ca86874 100644
--- a/activerecord/test/cases/json_shared_test_cases.rb
+++ b/activerecord/test/cases/json_shared_test_cases.rb
@@ -160,6 +160,17 @@ module JSONSharedTestCases
assert_not json.changed?
end
+ def test_changes_in_place_with_ruby_object
+ time = Time.now.utc
+ json = JsonDataType.create!(payload: time)
+
+ json.reload
+ assert_not json.changed?
+
+ json.payload = time
+ assert_not json.changed?
+ end
+
def test_assigning_string_literal
json = JsonDataType.create!(payload: "foo")
assert_equal "foo", json.payload
diff --git a/activerecord/test/cases/migration/command_recorder_test.rb b/activerecord/test/cases/migration/command_recorder_test.rb
index 802a969cb7..007926f1b9 100644
--- a/activerecord/test/cases/migration/command_recorder_test.rb
+++ b/activerecord/test/cases/migration/command_recorder_test.rb
@@ -211,11 +211,6 @@ module ActiveRecord
assert_equal [:remove_index, [:table, { name: "new_index" }]], remove
end
- def test_invert_add_index_with_no_options
- remove = @recorder.inverse_of :add_index, [:table, [:one, :two]]
- assert_equal [:remove_index, [:table, { column: [:one, :two] }]], remove
- end
-
def test_invert_remove_index
add = @recorder.inverse_of :remove_index, [:table, :one]
assert_equal [:add_index, [:table, :one]], add
diff --git a/activerecord/test/cases/migration/rename_table_test.rb b/activerecord/test/cases/migration/rename_table_test.rb
index 7bcabd0cc6..5da3ad33a3 100644
--- a/activerecord/test/cases/migration/rename_table_test.rb
+++ b/activerecord/test/cases/migration/rename_table_test.rb
@@ -79,10 +79,33 @@ module ActiveRecord
assert_equal ConnectionAdapters::PostgreSQL::Name.new("public", "octopi_#{pk}_seq"), seq
end
+ def test_renaming_table_renames_primary_key
+ connection.create_table :cats, id: :uuid, default: "uuid_generate_v4()"
+ rename_table :cats, :felines
+
+ assert connection.table_exists? :felines
+ refute connection.table_exists? :cats
+
+ primary_key_name = connection.select_values(<<-SQL.strip_heredoc, "SCHEMA")[0]
+ SELECT c.relname
+ FROM pg_class c
+ JOIN pg_index i
+ ON c.oid = i.indexrelid
+ WHERE i.indisprimary
+ AND i.indrelid = 'felines'::regclass
+ SQL
+
+ assert_equal "felines_pkey", primary_key_name
+ ensure
+ connection.drop_table :cats, if_exists: true
+ connection.drop_table :felines, if_exists: true
+ end
+
def test_renaming_table_doesnt_attempt_to_rename_non_existent_sequences
connection.create_table :cats, id: :uuid, default: "uuid_generate_v4()"
assert_nothing_raised { rename_table :cats, :felines }
assert connection.table_exists? :felines
+ refute connection.table_exists? :cats
ensure
connection.drop_table :cats, if_exists: true
connection.drop_table :felines, if_exists: true
diff --git a/activerecord/test/cases/relation/merging_test.rb b/activerecord/test/cases/relation/merging_test.rb
index 64866eaf2d..c3b39a9295 100644
--- a/activerecord/test/cases/relation/merging_test.rb
+++ b/activerecord/test/cases/relation/merging_test.rb
@@ -56,7 +56,7 @@ class RelationMergingTest < ActiveRecord::TestCase
def test_relation_merging_with_locks
devs = Developer.lock.where("salary >= 80000").order("id DESC").merge(Developer.limit(2))
- assert devs.locked.present?
+ assert devs.locked?
end
def test_relation_merging_with_preload
diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb
index 5d9aa99497..a305aa295a 100644
--- a/activerecord/test/cases/validations_test.rb
+++ b/activerecord/test/cases/validations_test.rb
@@ -167,6 +167,20 @@ class ValidationsTest < ActiveRecord::TestCase
assert topic.valid?
end
+ def test_numericality_validation_checks_against_raw_value
+ klass = Class.new(Topic) do
+ def self.model_name
+ ActiveModel::Name.new(self, nil, "Topic")
+ end
+ attribute :wibble, :decimal, scale: 2, precision: 9
+ validates_numericality_of :wibble, greater_than_or_equal_to: BigDecimal.new("97.18")
+ end
+
+ assert_not klass.new(wibble: "97.179").valid?
+ assert_not klass.new(wibble: 97.179).valid?
+ assert_not klass.new(wibble: BigDecimal.new("97.179")).valid?
+ end
+
def test_acceptance_validator_doesnt_require_db_connection
klass = Class.new(ActiveRecord::Base) do
self.table_name = "posts"
diff --git a/activerecord/test/fixtures/books.yml b/activerecord/test/fixtures/books.yml
index b3625ee72e..699623a6f9 100644
--- a/activerecord/test/fixtures/books.yml
+++ b/activerecord/test/fixtures/books.yml
@@ -25,6 +25,7 @@ ddd:
name: "Domain-Driven Design"
format: "hardcover"
status: 2
+ read_status: "forgotten"
tlg:
author_id: 1
diff --git a/activerecord/test/models/book.rb b/activerecord/test/models/book.rb
index 5f8a8a96dd..6466e1b341 100644
--- a/activerecord/test/models/book.rb
+++ b/activerecord/test/models/book.rb
@@ -8,7 +8,7 @@ class Book < ActiveRecord::Base
has_many :subscribers, through: :subscriptions
enum status: [:proposed, :written, :published]
- enum read_status: { unread: 0, reading: 2, read: 3 }
+ enum read_status: { unread: 0, reading: 2, read: 3, forgotten: nil }
enum nullable_status: [:single, :married]
enum language: [:english, :spanish, :french], _prefix: :in
enum author_visibility: [:visible, :invisible], _prefix: true
diff --git a/activerecord/test/models/category.rb b/activerecord/test/models/category.rb
index e8654dca01..4b2840c653 100644
--- a/activerecord/test/models/category.rb
+++ b/activerecord/test/models/category.rb
@@ -29,6 +29,15 @@ class Category < ActiveRecord::Base
has_many :authors_with_select, -> { select "authors.*, categorizations.post_id" }, through: :categorizations, source: :author
scope :general, -> { where(name: "General") }
+
+ # Should be delegated `ast` and `locked` to `arel`.
+ def self.ast
+ raise
+ end
+
+ def self.locked
+ raise
+ end
end
class SpecialCategory < Category
diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb
index 0420e2d15c..d9381ac9cf 100644
--- a/activerecord/test/models/topic.rb
+++ b/activerecord/test/models/topic.rb
@@ -14,7 +14,7 @@ class Topic < ActiveRecord::Base
scope :replied, -> { where "replies_count > 0" }
scope "approved_as_string", -> { where(approved: true) }
- scope :anonymous_extension, -> { all } do
+ scope :anonymous_extension, -> {} do
def one
1
end