diff options
Diffstat (limited to 'activerecord/lib/active_record')
22 files changed, 143 insertions, 90 deletions
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index 783a8366ce..d77d76cb1e 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -149,7 +149,7 @@ module ActiveRecord private def define_non_cyclic_method(name, &block) - return if method_defined?(name) + return if instance_methods(false).include?(name) define_method(name) do |*args| result = true; @_already_called ||= {} # Loop prevention for validation of associations diff --git a/activerecord/lib/active_record/collection_cache_key.rb b/activerecord/lib/active_record/collection_cache_key.rb index dfba78614e..61581b0451 100644 --- a/activerecord/lib/active_record/collection_cache_key.rb +++ b/activerecord/lib/active_record/collection_cache_key.rb @@ -16,7 +16,7 @@ module ActiveRecord collection = collection.send(:apply_join_dependency) end column_type = type_for_attribute(timestamp_column) - column = connection.column_name_from_arel_node(collection.arel_attribute(timestamp_column)) + column = connection.visitor.compile(collection.arel_attribute(timestamp_column)) select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp" if collection.has_limit_or_offset? diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb index 7a9e7add24..ad148efcfe 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "active_support/deprecation" + module ActiveRecord module ConnectionAdapters # :nodoc: module DatabaseLimits @@ -12,11 +14,13 @@ module ActiveRecord def column_name_length 64 end + deprecate :column_name_length # Returns the maximum length of a table name. def table_name_length 64 end + deprecate :table_name_length # Returns the maximum allowed length for an index name. This # limit is enforced by \Rails and is less than or equal to @@ -36,16 +40,19 @@ module ActiveRecord def columns_per_table 1024 end + deprecate :columns_per_table # Returns the maximum number of indexes per table. def indexes_per_table 16 end + deprecate :indexes_per_table # Returns the maximum number of columns in a multicolumn index. def columns_per_multicolumn_index 16 end + deprecate :columns_per_multicolumn_index # Returns the maximum number of elements in an IN (x,y,z) clause. # +nil+ means no limit. @@ -57,11 +64,13 @@ module ActiveRecord def sql_query_length 1048575 end + deprecate :sql_query_length # Returns maximum number of joins in a single query. def joins_per_query 256 end + deprecate :joins_per_query end end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index 1d36c3c8b1..fdc9ffa688 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -20,7 +20,7 @@ module ActiveRecord raise "Passing bind parameters with an arel AST is forbidden. " \ "The values must be stored on the AST directly" end - sql, binds = visitor.accept(arel_or_sql_string.ast, collector).value + sql, binds = visitor.compile(arel_or_sql_string.ast, collector) [sql.freeze, binds || []] else [arel_or_sql_string.dup.freeze, binds] @@ -32,11 +32,11 @@ module ActiveRecord # can be used to query the database repeatedly. def cacheable_query(klass, arel) # :nodoc: if prepared_statements - sql, binds = visitor.accept(arel.ast, collector).value + sql, binds = visitor.compile(arel.ast, collector) query = klass.query(sql) else collector = PartialQueryCollector.new - parts, binds = visitor.accept(arel.ast, collector).value + parts, binds = visitor.compile(arel.ast, collector) query = klass.partial_query(parts) end [query, binds] diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 84ea7a0c33..4a6e915b66 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -602,6 +602,7 @@ module ActiveRecord # The +type+ and +options+ parameters will be ignored if present. It can be helpful # to provide these in a migration's +change+ method so it can be reverted. # In that case, +type+ and +options+ will be used by #add_column. + # Indexes on the column are automatically removed. def remove_column(table_name, column_name, type = nil, options = {}) execute "ALTER TABLE #{quote_table_name(table_name)} #{remove_column_for_alter(table_name, column_name, type, options)}" end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index a62651daff..42ed9ce82d 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -360,6 +360,10 @@ module ActiveRecord def enable_extension(name) end + def advisory_locks_enabled? # :nodoc: + supports_advisory_locks? && @advisory_locks_enabled + end + # This is meant to be implemented by the adapters that support advisory # locks # @@ -490,11 +494,7 @@ module ActiveRecord end def column_name_for_operation(operation, node) # :nodoc: - column_name_from_arel_node(node) - end - - def column_name_from_arel_node(node) # :nodoc: - visitor.accept(node, Arel::Collectors::SQLString.new).value + visitor.compile(node) end def default_index_type?(index) # :nodoc: 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 ad045f85ef..5d4fc8324f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -53,8 +53,8 @@ module ActiveRecord @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit])) - if version < "5.1.10" - raise "Your version of MySQL (#{version_string}) is too old. Active Record supports MySQL >= 5.1.10." + if version < "5.5.8" + raise "Your version of MySQL (#{version_string}) is too old. Active Record supports MySQL >= 5.5.8." end end @@ -111,7 +111,15 @@ module ActiveRecord end def supports_advisory_locks? - @advisory_locks_enabled + true + end + + def supports_longer_index_key_prefix? + if mariadb? + version >= "10.2.2" + else + version >= "5.7.9" + end end def get_advisory_lock(lock_name, timeout = 0) # :nodoc: @@ -241,7 +249,7 @@ module ActiveRecord end # Create a new MySQL database with optional <tt>:charset</tt> and <tt>:collation</tt>. - # Charset defaults to utf8. + # Charset defaults to utf8mb4. # # Example: # create_database 'charset_test', charset: 'latin1', collation: 'latin1_bin' @@ -250,8 +258,12 @@ module ActiveRecord def create_database(name, options = {}) if options[:collation] execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT COLLATE #{quote_table_name(options[:collation])}" + elsif options[:charset] + execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset])}" + elsif supports_longer_index_key_prefix? + execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET `utf8mb4`" else - execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset] || 'utf8')}" + raise "Configure a supported :charset and ensure innodb_large_prefix is enabled to support indexes on varchar(255) string columns." end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 30e651ee63..3ee344a249 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -298,7 +298,7 @@ module ActiveRecord end def supports_advisory_locks? - @advisory_locks_enabled + true end def supports_explain? diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 9ec6ba14fd..392602bc0f 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -3,11 +3,14 @@ require "active_support/core_ext/hash/indifferent_access" require "active_support/core_ext/string/filters" require "concurrent/map" +require "set" module ActiveRecord module Core extend ActiveSupport::Concern + FILTERED = "[FILTERED]" # :nodoc: + included do ## # :singleton-method: @@ -123,6 +126,8 @@ module ActiveRecord class_attribute :default_connection_handler, instance_writer: false + self.filter_attributes = [] + def self.connection_handler ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler end @@ -134,7 +139,7 @@ module ActiveRecord self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new end - module ClassMethods # :nodoc: + module ClassMethods def initialize_find_by_cache # :nodoc: @find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new } end @@ -211,7 +216,7 @@ module ActiveRecord generated_association_methods end - def generated_association_methods + def generated_association_methods # :nodoc: @generated_association_methods ||= begin mod = const_set(:GeneratedAssociationMethods, Module.new) private_constant :GeneratedAssociationMethods @@ -221,8 +226,22 @@ module ActiveRecord end end + # Returns columns which shouldn't be exposed while calling +#inspect+. + def filter_attributes + if defined?(@filter_attributes) + @filter_attributes + else + superclass.filter_attributes + end + end + + # Specifies columns which shouldn't be exposed while calling +#inspect+. + def filter_attributes=(attributes_names) + @filter_attributes = attributes_names.map(&:to_s).to_set + end + # Returns a string like 'Post(id:integer, title:string, body:text)' - def inspect + def inspect # :nodoc: if self == Base super elsif abstract_class? @@ -238,7 +257,7 @@ module ActiveRecord end # Overwrite the default class equality method to provide support for decorated models. - def ===(object) + def ===(object) # :nodoc: object.is_a?(self) end @@ -492,7 +511,11 @@ module ActiveRecord inspection = if defined?(@attributes) && @attributes self.class.attribute_names.collect do |name| if has_attribute?(name) - "#{name}: #{attribute_for_inspect(name)}" + if filter_attribute?(name) + "#{name}: #{ActiveRecord::Core::FILTERED}" + else + "#{name}: #{attribute_for_inspect(name)}" + end end end.compact.join(", ") else @@ -510,13 +533,16 @@ module ActiveRecord if defined?(@attributes) && @attributes column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? } pp.seplist(column_names, proc { pp.text "," }) do |column_name| - column_value = read_attribute(column_name) pp.breakable " " pp.group(1) do pp.text column_name pp.text ":" pp.breakable - pp.pp column_value + if filter_attribute?(column_name) + pp.text ActiveRecord::Core::FILTERED + else + pp.pp read_attribute(column_name) + end end end else @@ -567,5 +593,9 @@ module ActiveRecord def custom_inspect_method_defined? self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner end + + def filter_attribute?(attribute_name) + self.class.filter_attributes.include?(attribute_name) && !read_attribute(attribute_name).nil? + end end end diff --git a/activerecord/lib/active_record/database_configurations.rb b/activerecord/lib/active_record/database_configurations.rb index a94f46d07f..9ff63c6e10 100644 --- a/activerecord/lib/active_record/database_configurations.rb +++ b/activerecord/lib/active_record/database_configurations.rb @@ -10,6 +10,7 @@ module ActiveRecord # application's database configuration hash or url string. class DatabaseConfigurations attr_reader :configurations + delegate :any?, to: :configurations def initialize(configurations = {}) @configurations = build_configs(configurations) @@ -18,8 +19,8 @@ module ActiveRecord # Collects the configs for the environment and optionally the specification # name passed in. To include replica configurations pass `include_replicas: true`. # - # If a spec name is provided a single DatabaseConfiguration object will be - # returned, otherwise an array of DatabaseConfiguration objects will be + # If a spec name is provided a single DatabaseConfig object will be + # returned, otherwise an array of DatabaseConfig objects will be # returned that corresponds with the environment and type requested. # # Options: @@ -53,7 +54,7 @@ module ActiveRecord # Returns the config hash that corresponds with the environment # # If the application has multiple databases `default_hash` will - # the first config hash for the environment. + # return the first config hash for the environment. # # { database: "my_db", adapter: "mysql2" } def default_hash(env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call.to_s) @@ -64,7 +65,7 @@ module ActiveRecord # Returns a single DatabaseConfig object based on the requested environment. # - # If the application has multiple databases `select_db_config` will return + # If the application has multiple databases `find_db_config` will return # the first DatabaseConfig for the environment. def find_db_config(env) configurations.find do |db_config| @@ -73,7 +74,7 @@ module ActiveRecord end end - # Returns the DatabaseConfig object as a Hash. + # Returns the DatabaseConfigurations object as a Hash. def to_h configs = configurations.reverse.inject({}) do |memo, db_config| memo.merge(db_config.to_legacy_hash) diff --git a/activerecord/lib/active_record/database_configurations/hash_config.rb b/activerecord/lib/active_record/database_configurations/hash_config.rb index 18ed7c0466..13ffe566cf 100644 --- a/activerecord/lib/active_record/database_configurations/hash_config.rb +++ b/activerecord/lib/active_record/database_configurations/hash_config.rb @@ -12,7 +12,7 @@ module ActiveRecord # Becomes: # # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 - # @env_name="development", @spec_name="primary", @config={"db_name"}> + # @env_name="development", @spec_name="primary", @config={"database"=>"db_name"}> # # Options are: # diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb index 6891c575c7..b25057acda 100644 --- a/activerecord/lib/active_record/inheritance.rb +++ b/activerecord/lib/active_record/inheritance.rb @@ -55,6 +55,10 @@ module ActiveRecord if has_attribute?(inheritance_column) subclass = subclass_from_attributes(attributes) + if subclass.nil? && scope_attributes = current_scope&.scope_for_create + subclass = subclass_from_attributes(scope_attributes) + end + if subclass.nil? && base_class? subclass = subclass_from_attributes(column_defaults) end diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index d68ed3cad9..ea53324829 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -1357,7 +1357,7 @@ module ActiveRecord end def use_advisory_lock? - Base.connection.supports_advisory_locks? + Base.connection.advisory_locks_enabled? end def with_advisory_lock diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 24af56cf0b..6eb2bfb452 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -70,17 +70,6 @@ module ActiveRecord instantiate_instance_of(klass, attributes, column_types, &block) end - # Given a class, an attributes hash, +instantiate_instance_of+ returns a - # new instance of the class. Accepts only keys as strings. - # - # This is private, don't call it. :) - # - # :nodoc: - def instantiate_instance_of(klass, attributes, column_types = {}, &block) - attributes = klass.attributes_builder.build_from_database(attributes, column_types) - klass.allocate.init_from_db(attributes, &block) - end - # Updates an object (or multiple objects) and saves it to the database, if validations pass. # The resulting object is returned whether the object was saved successfully to the database or not. # @@ -216,6 +205,13 @@ module ActiveRecord end private + # Given a class, an attributes hash, +instantiate_instance_of+ returns a + # new instance of the class. Accepts only keys as strings. + def instantiate_instance_of(klass, attributes, column_types = {}, &block) + attributes = klass.attributes_builder.build_from_database(attributes, column_types) + klass.allocate.init_from_db(attributes, &block) + end + # Called by +instantiate+ to decide which class to use for a new # record instance. # diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb index 7ece083fd4..b213754641 100644 --- a/activerecord/lib/active_record/railtie.rb +++ b/activerecord/lib/active_record/railtie.rb @@ -180,9 +180,7 @@ end_warning end initializer "active_record.set_executor_hooks" do - ActiveSupport.on_load(:active_record) do - ActiveRecord::QueryCache.install_executor_hooks - end + ActiveRecord::QueryCache.install_executor_hooks end initializer "active_record.add_watchable_files" do |app| @@ -235,5 +233,11 @@ MSG end end end + + initializer "active_record.set_filter_attributes" do + ActiveSupport.on_load(:active_record) do + self.filter_attributes += Rails.application.config.filter_parameters + end + end end end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 29a3ceab7d..86e5d14c81 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -62,7 +62,7 @@ module ActiveRecord # user = users.new { |user| user.name = 'Oscar' } # user.name # => Oscar def new(attributes = nil, &block) - scoping { klass.new(scope_for_create(attributes), &block) } + scoping { klass.new(attributes, &block) } end alias build new @@ -87,11 +87,7 @@ module ActiveRecord # users.create(name: nil) # validation on name # # => #<User id: nil, name: nil, ...> def create(attributes = nil, &block) - if attributes.is_a?(Array) - attributes.collect { |attr| create(attr, &block) } - else - scoping { klass.create(scope_for_create(attributes), &block) } - end + scoping { klass.create(attributes, &block) } end # Similar to #create, but calls @@ -101,11 +97,7 @@ module ActiveRecord # Expects arguments in the same format as # {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!]. def create!(attributes = nil, &block) - if attributes.is_a?(Array) - attributes.collect { |attr| create!(attr, &block) } - else - scoping { klass.create!(scope_for_create(attributes), &block) } - end + scoping { klass.create!(attributes, &block) } end def first_or_create(attributes = nil, &block) # :nodoc: @@ -315,10 +307,7 @@ module ActiveRecord # Please check unscoped if you want to remove all previous scopes (including # the default_scope) during the execution of a block. def scoping - previous, klass.current_scope = klass.current_scope(true), self unless @delegate_to_klass - yield - ensure - klass.current_scope = previous unless @delegate_to_klass + @delegate_to_klass ? yield : klass._scoping(self) { yield } end def _exec_scope(*args, &block) # :nodoc: @@ -554,10 +543,8 @@ module ActiveRecord where_clause.to_h(relation_table_name) end - def scope_for_create(attributes = nil) - scope = where_values_hash.merge!(create_with_value.stringify_keys) - scope.merge!(attributes) if attributes - scope + def scope_for_create + where_values_hash.merge!(create_with_value.stringify_keys) end # Returns true if relation needs eager loading. diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index c5562c1ff0..0fabfe5518 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -398,7 +398,7 @@ module ActiveRecord def limited_ids_for(relation) values = @klass.connection.columns_for_distinct( - connection.column_name_from_arel_node(arel_attribute(primary_key)), + connection.visitor.compile(arel_attribute(primary_key)), relation.order_values ) diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index f734cd0ad8..cb70b8bcde 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -57,10 +57,14 @@ module ActiveRecord end def build_bind_attribute(column_name, value) - attr = Relation::QueryAttribute.new(column_name.to_s, value, table.type(column_name)) + attr = build_query_attribute(column_name, value) Arel::Nodes::BindParam.new(attr) end + def build_query_attribute(column_name, value) + Relation::QueryAttribute.new(column_name.to_s, value, table.type(column_name)) + end + protected def expand_from_hash(attributes) return ["1=0"] if attributes.empty? diff --git a/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb index e5191fa38a..0895b9fba6 100644 --- a/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb +++ b/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb @@ -21,10 +21,11 @@ module ActiveRecord when 0 then NullPredicate when 1 then predicate_builder.build(attribute, values.first) else - bind_values = values.map do |v| - predicate_builder.build_bind_attribute(attribute.name, v) - end - attribute.in(bind_values) + values.map! do |v| + attr = predicate_builder.build_query_attribute(attribute.name, v) + attr.value_for_database if attr.boundable? + end.compact! + values.empty? ? NullPredicate : attribute.in(values) end unless nils.empty? diff --git a/activerecord/lib/active_record/scoping.rb b/activerecord/lib/active_record/scoping.rb index 01ac56570a..9eba1254a4 100644 --- a/activerecord/lib/active_record/scoping.rb +++ b/activerecord/lib/active_record/scoping.rb @@ -12,14 +12,6 @@ module ActiveRecord end module ClassMethods # :nodoc: - def current_scope(skip_inherited_scope = false) - ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope) - end - - def current_scope=(scope) - ScopeRegistry.set_value_for(:current_scope, self, scope) - end - # Collects attributes from scopes that should be applied when creating # an AR instance for the particular class this is called on. def scope_attributes @@ -30,6 +22,15 @@ module ActiveRecord def scope_attributes? current_scope end + + private + def current_scope(skip_inherited_scope = false) + ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope) + end + + def current_scope=(scope) + ScopeRegistry.set_value_for(:current_scope, self, scope) + end end def populate_with_current_scope_attributes # :nodoc: diff --git a/activerecord/lib/active_record/scoping/default.rb b/activerecord/lib/active_record/scoping/default.rb index 8c612df27a..6caf9b3251 100644 --- a/activerecord/lib/active_record/scoping/default.rb +++ b/activerecord/lib/active_record/scoping/default.rb @@ -31,7 +31,14 @@ module ActiveRecord # Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10" # } def unscoped - block_given? ? relation.scoping { yield } : relation + block_given? ? _scoping(relation) { yield } : relation + end + + def _scoping(relation) # :nodoc: + previous, self.current_scope = current_scope(true), relation + yield + ensure + self.current_scope = previous end # Are there attributes associated with this scope? diff --git a/activerecord/lib/active_record/scoping/named.rb b/activerecord/lib/active_record/scoping/named.rb index a784001587..573d97b819 100644 --- a/activerecord/lib/active_record/scoping/named.rb +++ b/activerecord/lib/active_record/scoping/named.rb @@ -24,13 +24,13 @@ module ActiveRecord # You can define a scope that applies to all finders using # {default_scope}[rdoc-ref:Scoping::Default::ClassMethods#default_scope]. def all - current_scope = self.current_scope + scope = current_scope - if current_scope - if self == current_scope.klass - current_scope.clone + if scope + if self == scope.klass + scope.clone else - relation.merge!(current_scope) + relation.merge!(scope) end else default_scoped @@ -38,9 +38,7 @@ module ActiveRecord end def scope_for_association(scope = relation) # :nodoc: - current_scope = self.current_scope - - if current_scope && current_scope.empty_scope? + if current_scope&.empty_scope? scope else default_scoped(scope) @@ -182,15 +180,13 @@ module ActiveRecord if body.respond_to?(:to_proc) singleton_class.send(:define_method, name) do |*args| - scope = all - scope = scope._exec_scope(*args, &body) + scope = all._exec_scope(*args, &body) scope = scope.extending(extension) if extension scope end else singleton_class.send(:define_method, name) do |*args| - scope = all - scope = scope.scoping { body.call(*args) || scope } + scope = body.call(*args) || all scope = scope.extending(extension) if extension scope end |