activerecord 5.2.5 → 6.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +299 -748
- data/MIT-LICENSE +3 -1
- data/README.rdoc +1 -1
- data/examples/performance.rb +1 -1
- data/lib/active_record.rb +2 -1
- data/lib/active_record/aggregations.rb +4 -2
- data/lib/active_record/associations.rb +16 -12
- data/lib/active_record/associations/association.rb +35 -19
- data/lib/active_record/associations/association_scope.rb +4 -6
- data/lib/active_record/associations/belongs_to_association.rb +36 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
- data/lib/active_record/associations/builder/belongs_to.rb +14 -50
- data/lib/active_record/associations/builder/collection_association.rb +3 -3
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
- data/lib/active_record/associations/collection_association.rb +11 -25
- data/lib/active_record/associations/collection_proxy.rb +32 -6
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +25 -18
- data/lib/active_record/associations/has_one_association.rb +28 -30
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency.rb +15 -20
- data/lib/active_record/associations/join_dependency/join_association.rb +11 -26
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/preloader.rb +32 -29
- data/lib/active_record/associations/preloader/association.rb +1 -2
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/attribute_assignment.rb +7 -10
- data/lib/active_record/attribute_methods.rb +34 -56
- data/lib/active_record/attribute_methods/dirty.rb +64 -26
- data/lib/active_record/attribute_methods/primary_key.rb +8 -7
- data/lib/active_record/attribute_methods/read.rb +16 -48
- data/lib/active_record/attribute_methods/serialization.rb +1 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
- data/lib/active_record/attribute_methods/write.rb +15 -16
- data/lib/active_record/autosave_association.rb +7 -21
- data/lib/active_record/base.rb +2 -2
- data/lib/active_record/callbacks.rb +3 -17
- data/lib/active_record/collection_cache_key.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +13 -36
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +25 -84
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +17 -14
- data/lib/active_record/connection_adapters/abstract/quoting.rb +5 -11
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -11
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +30 -13
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +0 -2
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +41 -27
- data/lib/active_record/connection_adapters/abstract/transaction.rb +81 -52
- data/lib/active_record/connection_adapters/abstract_adapter.rb +95 -31
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +65 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +5 -9
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +29 -7
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +65 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -4
- data/lib/active_record/connection_adapters/postgresql/column.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +16 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +11 -36
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +9 -2
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +38 -20
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -56
- data/lib/active_record/connection_adapters/schema_cache.rb +5 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +5 -5
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +14 -9
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +95 -62
- data/lib/active_record/connection_handling.rb +132 -26
- data/lib/active_record/core.rb +76 -43
- data/lib/active_record/counter_cache.rb +4 -29
- data/lib/active_record/database_configurations.rb +184 -0
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +74 -0
- data/lib/active_record/enum.rb +22 -7
- data/lib/active_record/errors.rb +24 -21
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +140 -472
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +12 -2
- data/lib/active_record/integration.rb +56 -16
- data/lib/active_record/internal_metadata.rb +5 -1
- data/lib/active_record/locking/optimistic.rb +2 -2
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +7 -26
- data/lib/active_record/migration.rb +38 -37
- data/lib/active_record/migration/command_recorder.rb +35 -5
- data/lib/active_record/migration/compatibility.rb +34 -16
- data/lib/active_record/model_schema.rb +30 -9
- data/lib/active_record/nested_attributes.rb +2 -2
- data/lib/active_record/no_touching.rb +7 -0
- data/lib/active_record/persistence.rb +18 -7
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +19 -11
- data/lib/active_record/railtie.rb +71 -42
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +94 -43
- data/lib/active_record/reflection.rb +60 -44
- data/lib/active_record/relation.rb +150 -69
- data/lib/active_record/relation/batches.rb +13 -10
- data/lib/active_record/relation/calculations.rb +38 -28
- data/lib/active_record/relation/delegation.rb +4 -13
- data/lib/active_record/relation/finder_methods.rb +12 -25
- data/lib/active_record/relation/merger.rb +2 -6
- data/lib/active_record/relation/predicate_builder.rb +4 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/query_attribute.rb +15 -12
- data/lib/active_record/relation/query_methods.rb +29 -52
- data/lib/active_record/relation/where_clause.rb +4 -0
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/result.rb +30 -11
- data/lib/active_record/sanitization.rb +2 -39
- data/lib/active_record/schema.rb +1 -10
- data/lib/active_record/schema_dumper.rb +12 -6
- data/lib/active_record/schema_migration.rb +4 -0
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/scoping/default.rb +10 -3
- data/lib/active_record/scoping/named.rb +10 -14
- data/lib/active_record/statement_cache.rb +32 -5
- data/lib/active_record/store.rb +39 -8
- data/lib/active_record/table_metadata.rb +1 -4
- data/lib/active_record/tasks/database_tasks.rb +89 -23
- data/lib/active_record/tasks/mysql_database_tasks.rb +2 -4
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
- data/lib/active_record/test_databases.rb +38 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +4 -6
- data/lib/active_record/transactions.rb +3 -22
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type.rb +3 -4
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type_caster/connection.rb +1 -6
- data/lib/active_record/type_caster/map.rb +1 -4
- data/lib/active_record/validations/uniqueness.rb +13 -25
- data/lib/arel.rb +44 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes.rb +67 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +63 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values.rb +16 -0
- data/lib/arel/nodes/values_list.rb +24 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +257 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/visitors/depth_first.rb +199 -0
- data/lib/arel/visitors/dot.rb +292 -0
- data/lib/arel/visitors/ibm_db.rb +21 -0
- data/lib/arel/visitors/informix.rb +56 -0
- data/lib/arel/visitors/mssql.rb +143 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +159 -0
- data/lib/arel/visitors/oracle12.rb +67 -0
- data/lib/arel/visitors/postgresql.rb +116 -0
- data/lib/arel/visitors/sqlite.rb +39 -0
- data/lib/arel/visitors/to_sql.rb +913 -0
- data/lib/arel/visitors/visitor.rb +42 -0
- data/lib/arel/visitors/where_sql.rb +23 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/rails/generators/active_record/migration.rb +14 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
- metadata +104 -26
| @@ -251,25 +251,28 @@ module ActiveRecord | |
| 251 251 | 
             
                      end
         | 
| 252 252 | 
             
                    end
         | 
| 253 253 |  | 
| 254 | 
            -
                     | 
| 255 | 
            -
             | 
| 254 | 
            +
                    batch_relation = relation.where(
         | 
| 255 | 
            +
                      bind_attribute(primary_key, primary_key_offset) { |attr, bind| attr.gt(bind) }
         | 
| 256 | 
            +
                    )
         | 
| 256 257 | 
             
                  end
         | 
| 257 258 | 
             
                end
         | 
| 258 259 |  | 
| 259 260 | 
             
                private
         | 
| 260 261 |  | 
| 261 262 | 
             
                  def apply_limits(relation, start, finish)
         | 
| 262 | 
            -
                    if start
         | 
| 263 | 
            -
             | 
| 264 | 
            -
                      relation = relation.where(arel_attribute(primary_key).gteq(Arel::Nodes::BindParam.new(attr)))
         | 
| 265 | 
            -
                    end
         | 
| 266 | 
            -
                    if finish
         | 
| 267 | 
            -
                      attr = Relation::QueryAttribute.new(primary_key, finish, klass.type_for_attribute(primary_key))
         | 
| 268 | 
            -
                      relation = relation.where(arel_attribute(primary_key).lteq(Arel::Nodes::BindParam.new(attr)))
         | 
| 269 | 
            -
                    end
         | 
| 263 | 
            +
                    relation = apply_start_limit(relation, start) if start
         | 
| 264 | 
            +
                    relation = apply_finish_limit(relation, finish) if finish
         | 
| 270 265 | 
             
                    relation
         | 
| 271 266 | 
             
                  end
         | 
| 272 267 |  | 
| 268 | 
            +
                  def apply_start_limit(relation, start)
         | 
| 269 | 
            +
                    relation.where(bind_attribute(primary_key, start) { |attr, bind| attr.gteq(bind) })
         | 
| 270 | 
            +
                  end
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                  def apply_finish_limit(relation, finish)
         | 
| 273 | 
            +
                    relation.where(bind_attribute(primary_key, finish) { |attr, bind| attr.lteq(bind) })
         | 
| 274 | 
            +
                  end
         | 
| 275 | 
            +
             | 
| 273 276 | 
             
                  def batch_order
         | 
| 274 277 | 
             
                    arel_attribute(primary_key).asc
         | 
| 275 278 | 
             
                  end
         | 
| @@ -41,15 +41,13 @@ module ActiveRecord | |
| 41 41 | 
             
                def count(column_name = nil)
         | 
| 42 42 | 
             
                  if block_given?
         | 
| 43 43 | 
             
                    unless column_name.nil?
         | 
| 44 | 
            -
                       | 
| 45 | 
            -
                        "When `count' is called with a block, it ignores other arguments. " \
         | 
| 46 | 
            -
                        "This behavior is now deprecated and will result in an ArgumentError in Rails 6.0."
         | 
| 44 | 
            +
                      raise ArgumentError, "Column name argument is not supported when a block is passed."
         | 
| 47 45 | 
             
                    end
         | 
| 48 46 |  | 
| 49 | 
            -
                     | 
| 47 | 
            +
                    super()
         | 
| 48 | 
            +
                  else
         | 
| 49 | 
            +
                    calculate(:count, column_name)
         | 
| 50 50 | 
             
                  end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                  calculate(:count, column_name)
         | 
| 53 51 | 
             
                end
         | 
| 54 52 |  | 
| 55 53 | 
             
                # Calculates the average value on a given column. Returns +nil+ if there's
         | 
| @@ -86,15 +84,13 @@ module ActiveRecord | |
| 86 84 | 
             
                def sum(column_name = nil)
         | 
| 87 85 | 
             
                  if block_given?
         | 
| 88 86 | 
             
                    unless column_name.nil?
         | 
| 89 | 
            -
                       | 
| 90 | 
            -
                        "When `sum' is called with a block, it ignores other arguments. " \
         | 
| 91 | 
            -
                        "This behavior is now deprecated and will result in an ArgumentError in Rails 6.0."
         | 
| 87 | 
            +
                      raise ArgumentError, "Column name argument is not supported when a block is passed."
         | 
| 92 88 | 
             
                    end
         | 
| 93 89 |  | 
| 94 | 
            -
                     | 
| 90 | 
            +
                    super()
         | 
| 91 | 
            +
                  else
         | 
| 92 | 
            +
                    calculate(:sum, column_name)
         | 
| 95 93 | 
             
                  end
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                  calculate(:sum, column_name)
         | 
| 98 94 | 
             
                end
         | 
| 99 95 |  | 
| 100 96 | 
             
                # This calculates aggregate values in the given column. Methods for #count, #sum, #average,
         | 
| @@ -133,12 +129,11 @@ module ActiveRecord | |
| 133 129 | 
             
                    relation = apply_join_dependency
         | 
| 134 130 |  | 
| 135 131 | 
             
                    if operation.to_s.downcase == "count"
         | 
| 136 | 
            -
                       | 
| 137 | 
            -
                        relation.distinct!
         | 
| 138 | 
            -
                        relation.select_values = [ klass.primary_key || table[Arel.star] ]
         | 
| 139 | 
            -
                      end
         | 
| 132 | 
            +
                      relation.distinct!
         | 
| 140 133 | 
             
                      # PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCT
         | 
| 141 | 
            -
                       | 
| 134 | 
            +
                      if (column_name == :all || column_name.nil?) && select_values.empty?
         | 
| 135 | 
            +
                        relation.order_values = []
         | 
| 136 | 
            +
                      end
         | 
| 142 137 | 
             
                    end
         | 
| 143 138 |  | 
| 144 139 | 
             
                    relation.calculate(operation, column_name)
         | 
| @@ -191,14 +186,34 @@ module ActiveRecord | |
| 191 186 | 
             
                    relation = apply_join_dependency
         | 
| 192 187 | 
             
                    relation.pluck(*column_names)
         | 
| 193 188 | 
             
                  else
         | 
| 194 | 
            -
                     | 
| 189 | 
            +
                    disallow_raw_sql!(column_names)
         | 
| 195 190 | 
             
                    relation = spawn
         | 
| 196 | 
            -
                    relation.select_values = column_names
         | 
| 191 | 
            +
                    relation.select_values = column_names.map { |cn|
         | 
| 192 | 
            +
                      @klass.has_attribute?(cn) || @klass.attribute_alias?(cn) ? arel_attribute(cn) : cn
         | 
| 193 | 
            +
                    }
         | 
| 197 194 | 
             
                    result = skip_query_cache_if_necessary { klass.connection.select_all(relation.arel, nil) }
         | 
| 198 195 | 
             
                    result.cast_values(klass.attribute_types)
         | 
| 199 196 | 
             
                  end
         | 
| 200 197 | 
             
                end
         | 
| 201 198 |  | 
| 199 | 
            +
                # Pick the value(s) from the named column(s) in the current relation.
         | 
| 200 | 
            +
                # This is short-hand for <tt>relation.limit(1).pluck(*column_names).first</tt>, and is primarily useful
         | 
| 201 | 
            +
                # when you have a relation that's already narrowed down to a single row.
         | 
| 202 | 
            +
                #
         | 
| 203 | 
            +
                # Just like #pluck, #pick will only load the actual value, not the entire record object, so it's also
         | 
| 204 | 
            +
                # more efficient. The value is, again like with pluck, typecast by the column type.
         | 
| 205 | 
            +
                #
         | 
| 206 | 
            +
                #   Person.where(id: 1).pick(:name)
         | 
| 207 | 
            +
                #   # SELECT people.name FROM people WHERE id = 1 LIMIT 1
         | 
| 208 | 
            +
                #   # => 'David'
         | 
| 209 | 
            +
                #
         | 
| 210 | 
            +
                #   Person.where(id: 1).pick(:name, :email_address)
         | 
| 211 | 
            +
                #   # SELECT people.name, people.email_address FROM people WHERE id = 1 LIMIT 1
         | 
| 212 | 
            +
                #   # => [ 'David', 'david@loudthinking.com' ]
         | 
| 213 | 
            +
                def pick(*column_names)
         | 
| 214 | 
            +
                  limit(1).pluck(*column_names).first
         | 
| 215 | 
            +
                end
         | 
| 216 | 
            +
             | 
| 202 217 | 
             
                # Pluck all the ID's for the relation using the table's primary key
         | 
| 203 218 | 
             
                #
         | 
| 204 219 | 
             
                #   Person.ids # SELECT people.id FROM people
         | 
| @@ -208,6 +223,7 @@ module ActiveRecord | |
| 208 223 | 
             
                end
         | 
| 209 224 |  | 
| 210 225 | 
             
                private
         | 
| 226 | 
            +
             | 
| 211 227 | 
             
                  def has_include?(column_name)
         | 
| 212 228 | 
             
                    eager_loading? || (includes_values.present? && column_name && column_name != :all)
         | 
| 213 229 | 
             
                  end
         | 
| @@ -222,12 +238,10 @@ module ActiveRecord | |
| 222 238 | 
             
                    if operation == "count"
         | 
| 223 239 | 
             
                      column_name ||= select_for_count
         | 
| 224 240 | 
             
                      if column_name == :all
         | 
| 225 | 
            -
                        if  | 
| 226 | 
            -
                          distinct = distinct_select?(select_for_count) if group_values.empty?
         | 
| 227 | 
            -
                        elsif group_values.any? || select_values.empty? && order_values.empty?
         | 
| 241 | 
            +
                        if distinct && (group_values.any? || select_values.empty? && order_values.empty?)
         | 
| 228 242 | 
             
                          column_name = primary_key
         | 
| 229 243 | 
             
                        end
         | 
| 230 | 
            -
                      elsif  | 
| 244 | 
            +
                      elsif column_name.is_a?(::String) && /\bDISTINCT[\s(]/i.match?(column_name)
         | 
| 231 245 | 
             
                        distinct = nil
         | 
| 232 246 | 
             
                      end
         | 
| 233 247 | 
             
                    end
         | 
| @@ -239,10 +253,6 @@ module ActiveRecord | |
| 239 253 | 
             
                    end
         | 
| 240 254 | 
             
                  end
         | 
| 241 255 |  | 
| 242 | 
            -
                  def distinct_select?(column_name)
         | 
| 243 | 
            -
                    column_name.is_a?(::String) && /\bDISTINCT[\s(]/i.match?(column_name)
         | 
| 244 | 
            -
                  end
         | 
| 245 | 
            -
             | 
| 246 256 | 
             
                  def aggregate_column(column_name)
         | 
| 247 257 | 
             
                    return column_name if Arel::Expressions === column_name
         | 
| 248 258 |  | 
| @@ -387,7 +397,7 @@ module ActiveRecord | |
| 387 397 | 
             
                    case operation
         | 
| 388 398 | 
             
                    when "count"   then value.to_i
         | 
| 389 399 | 
             
                    when "sum"     then type.deserialize(value || 0)
         | 
| 390 | 
            -
                    when "average" then value | 
| 400 | 
            +
                    when "average" then value&.respond_to?(:to_d) ? value.to_d : value
         | 
| 391 401 | 
             
                    else type.deserialize(value)
         | 
| 392 402 | 
             
                    end
         | 
| 393 403 | 
             
                  end
         | 
| @@ -18,7 +18,7 @@ module ActiveRecord | |
| 18 18 | 
             
                        include ClassSpecificRelation
         | 
| 19 19 | 
             
                      }
         | 
| 20 20 | 
             
                      include_relation_methods(delegate)
         | 
| 21 | 
            -
                      mangled_name = klass.name.gsub("::" | 
| 21 | 
            +
                      mangled_name = klass.name.gsub("::", "_")
         | 
| 22 22 | 
             
                      const_set mangled_name, delegate
         | 
| 23 23 | 
             
                      private_constant mangled_name
         | 
| 24 24 |  | 
| @@ -33,7 +33,7 @@ module ActiveRecord | |
| 33 33 |  | 
| 34 34 | 
             
                  protected
         | 
| 35 35 | 
             
                    def include_relation_methods(delegate)
         | 
| 36 | 
            -
                      superclass.include_relation_methods(delegate) unless base_class | 
| 36 | 
            +
                      superclass.include_relation_methods(delegate) unless base_class?
         | 
| 37 37 | 
             
                      delegate.include generated_relation_methods
         | 
| 38 38 | 
             
                    end
         | 
| 39 39 |  | 
| @@ -54,7 +54,7 @@ module ActiveRecord | |
| 54 54 | 
             
                          end
         | 
| 55 55 | 
             
                        RUBY
         | 
| 56 56 | 
             
                      else
         | 
| 57 | 
            -
                        generated_relation_methods. | 
| 57 | 
            +
                        generated_relation_methods.define_method(method) do |*args, &block|
         | 
| 58 58 | 
             
                          scoping { klass.public_send(method, *args, &block) }
         | 
| 59 59 | 
             
                        end
         | 
| 60 60 | 
             
                      end
         | 
| @@ -68,7 +68,7 @@ module ActiveRecord | |
| 68 68 | 
             
                # may vary depending on the klass of a relation, so we create a subclass of Relation
         | 
| 69 69 | 
             
                # for each different klass, and the delegations are compiled into that subclass only.
         | 
| 70 70 |  | 
| 71 | 
            -
                delegate :to_xml, :encode_with, :length, :each, : | 
| 71 | 
            +
                delegate :to_xml, :encode_with, :length, :each, :join,
         | 
| 72 72 | 
             
                         :[], :&, :|, :+, :-, :sample, :reverse, :rotate, :compact, :in_groups, :in_groups_of,
         | 
| 73 73 | 
             
                         :to_sentence, :to_formatted_s, :as_json,
         | 
| 74 74 | 
             
                         :shuffle, :split, :slice, :index, :rindex, to: :records
         | 
| @@ -112,15 +112,6 @@ module ActiveRecord | |
| 112 112 | 
             
                      if @klass.respond_to?(method)
         | 
| 113 113 | 
             
                        self.class.delegate_to_scoped_klass(method)
         | 
| 114 114 | 
             
                        scoping { @klass.public_send(method, *args, &block) }
         | 
| 115 | 
            -
                      elsif @delegate_to_klass && @klass.respond_to?(method, true)
         | 
| 116 | 
            -
                        ActiveSupport::Deprecation.warn \
         | 
| 117 | 
            -
                          "Delegating missing #{method} method to #{@klass}. " \
         | 
| 118 | 
            -
                          "Accessibility of private/protected class methods in :scope is deprecated and will be removed in Rails 6.0."
         | 
| 119 | 
            -
                        @klass.send(method, *args, &block)
         | 
| 120 | 
            -
                      elsif arel.respond_to?(method)
         | 
| 121 | 
            -
                        ActiveSupport::Deprecation.warn \
         | 
| 122 | 
            -
                          "Delegating #{method} to arel is deprecated and will be removed in Rails 6.0."
         | 
| 123 | 
            -
                        arel.public_send(method, *args, &block)
         | 
| 124 115 | 
             
                      else
         | 
| 125 116 | 
             
                        super
         | 
| 126 117 | 
             
                      end
         | 
| @@ -79,17 +79,12 @@ module ActiveRecord | |
| 79 79 | 
             
                #   Post.find_by "published_at < ?", 2.weeks.ago
         | 
| 80 80 | 
             
                def find_by(arg, *args)
         | 
| 81 81 | 
             
                  where(arg, *args).take
         | 
| 82 | 
            -
                rescue ::RangeError
         | 
| 83 | 
            -
                  nil
         | 
| 84 82 | 
             
                end
         | 
| 85 83 |  | 
| 86 84 | 
             
                # Like #find_by, except that if no record is found, raises
         | 
| 87 85 | 
             
                # an ActiveRecord::RecordNotFound error.
         | 
| 88 86 | 
             
                def find_by!(arg, *args)
         | 
| 89 87 | 
             
                  where(arg, *args).take!
         | 
| 90 | 
            -
                rescue ::RangeError
         | 
| 91 | 
            -
                  raise RecordNotFound.new("Couldn't find #{@klass.name} with an out of range value",
         | 
| 92 | 
            -
                                           @klass.name, @klass.primary_key)
         | 
| 93 88 | 
             
                end
         | 
| 94 89 |  | 
| 95 90 | 
             
                # Gives a record (or N records if a parameter is supplied) without any implied
         | 
| @@ -312,6 +307,8 @@ module ActiveRecord | |
| 312 307 |  | 
| 313 308 | 
             
                  return false if !conditions || limit_value == 0
         | 
| 314 309 |  | 
| 310 | 
            +
                  conditions = sanitize_forbidden_attributes(conditions)
         | 
| 311 | 
            +
             | 
| 315 312 | 
             
                  if eager_loading?
         | 
| 316 313 | 
             
                    relation = apply_join_dependency(eager_loading: false)
         | 
| 317 314 | 
             
                    return relation.exists?(conditions)
         | 
| @@ -319,9 +316,7 @@ module ActiveRecord | |
| 319 316 |  | 
| 320 317 | 
             
                  relation = construct_relation_for_exists(conditions)
         | 
| 321 318 |  | 
| 322 | 
            -
                  skip_query_cache_if_necessary { connection. | 
| 323 | 
            -
                rescue ::RangeError
         | 
| 324 | 
            -
                  false
         | 
| 319 | 
            +
                  skip_query_cache_if_necessary { connection.select_value(relation.arel, "#{name} Exists") } ? true : false
         | 
| 325 320 | 
             
                end
         | 
| 326 321 |  | 
| 327 322 | 
             
                # This method is called whenever no records are found with either a single
         | 
| @@ -338,14 +333,14 @@ module ActiveRecord | |
| 338 333 | 
             
                  name = @klass.name
         | 
| 339 334 |  | 
| 340 335 | 
             
                  if ids.nil?
         | 
| 341 | 
            -
                    error = "Couldn't find #{name}" | 
| 336 | 
            +
                    error = +"Couldn't find #{name}"
         | 
| 342 337 | 
             
                    error << " with#{conditions}" if conditions
         | 
| 343 338 | 
             
                    raise RecordNotFound.new(error, name, key)
         | 
| 344 339 | 
             
                  elsif Array(ids).size == 1
         | 
| 345 340 | 
             
                    error = "Couldn't find #{name} with '#{key}'=#{ids}#{conditions}"
         | 
| 346 341 | 
             
                    raise RecordNotFound.new(error, name, key, ids)
         | 
| 347 342 | 
             
                  else
         | 
| 348 | 
            -
                    error = "Couldn't find all #{name.pluralize} with '#{key}': " | 
| 343 | 
            +
                    error = +"Couldn't find all #{name.pluralize} with '#{key}': "
         | 
| 349 344 | 
             
                    error << "(#{ids.join(", ")})#{conditions} (found #{result_size} results, but was looking for #{expected_size})."
         | 
| 350 345 | 
             
                    error << " Couldn't find #{name.pluralize(not_found_ids.size)} with #{key.to_s.pluralize(not_found_ids.size)} #{not_found_ids.join(', ')}." if not_found_ids
         | 
| 351 346 | 
             
                    raise RecordNotFound.new(error, name, key, ids)
         | 
| @@ -359,11 +354,7 @@ module ActiveRecord | |
| 359 354 | 
             
                  end
         | 
| 360 355 |  | 
| 361 356 | 
             
                  def construct_relation_for_exists(conditions)
         | 
| 362 | 
            -
                     | 
| 363 | 
            -
                      relation = except(:order).limit!(1)
         | 
| 364 | 
            -
                    else
         | 
| 365 | 
            -
                      relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
         | 
| 366 | 
            -
                    end
         | 
| 357 | 
            +
                    relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
         | 
| 367 358 |  | 
| 368 359 | 
             
                    case conditions
         | 
| 369 360 | 
             
                    when Array, Hash
         | 
| @@ -375,15 +366,14 @@ module ActiveRecord | |
| 375 366 | 
             
                    relation
         | 
| 376 367 | 
             
                  end
         | 
| 377 368 |  | 
| 378 | 
            -
                  def construct_join_dependency
         | 
| 379 | 
            -
                    including = eager_load_values + includes_values
         | 
| 369 | 
            +
                  def construct_join_dependency(associations)
         | 
| 380 370 | 
             
                    ActiveRecord::Associations::JoinDependency.new(
         | 
| 381 | 
            -
                      klass, table,  | 
| 371 | 
            +
                      klass, table, associations
         | 
| 382 372 | 
             
                    )
         | 
| 383 373 | 
             
                  end
         | 
| 384 374 |  | 
| 385 375 | 
             
                  def apply_join_dependency(eager_loading: group_values.empty?)
         | 
| 386 | 
            -
                    join_dependency = construct_join_dependency
         | 
| 376 | 
            +
                    join_dependency = construct_join_dependency(eager_load_values + includes_values)
         | 
| 387 377 | 
             
                    relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
         | 
| 388 378 |  | 
| 389 379 | 
             
                    if eager_loading && !using_limitable_reflections?(join_dependency.reflections)
         | 
| @@ -403,7 +393,7 @@ module ActiveRecord | |
| 403 393 |  | 
| 404 394 | 
             
                  def limited_ids_for(relation)
         | 
| 405 395 | 
             
                    values = @klass.connection.columns_for_distinct(
         | 
| 406 | 
            -
                      connection. | 
| 396 | 
            +
                      connection.visitor.compile(arel_attribute(primary_key)),
         | 
| 407 397 | 
             
                      relation.order_values
         | 
| 408 398 | 
             
                    )
         | 
| 409 399 |  | 
| @@ -437,9 +427,6 @@ module ActiveRecord | |
| 437 427 | 
             
                    else
         | 
| 438 428 | 
             
                      find_some(ids)
         | 
| 439 429 | 
             
                    end
         | 
| 440 | 
            -
                  rescue ::RangeError
         | 
| 441 | 
            -
                    error_message = "Couldn't find #{model_name} with an out of range ID"
         | 
| 442 | 
            -
                    raise RecordNotFound.new(error_message, model_name, primary_key, ids)
         | 
| 443 430 | 
             
                  end
         | 
| 444 431 |  | 
| 445 432 | 
             
                  def find_one(id)
         | 
| @@ -555,8 +542,8 @@ module ActiveRecord | |
| 555 542 | 
             
                  end
         | 
| 556 543 |  | 
| 557 544 | 
             
                  def ordered_relation
         | 
| 558 | 
            -
                    if order_values.empty? && primary_key
         | 
| 559 | 
            -
                      order(arel_attribute(primary_key).asc)
         | 
| 545 | 
            +
                    if order_values.empty? && (implicit_order_column || primary_key)
         | 
| 546 | 
            +
                      order(arel_attribute(implicit_order_column || primary_key).asc)
         | 
| 560 547 | 
             
                    else
         | 
| 561 548 | 
             
                      self
         | 
| 562 549 | 
             
                    end
         | 
| @@ -120,9 +120,7 @@ module ActiveRecord | |
| 120 120 | 
             
                        joins_dependency = other.joins_values.map do |join|
         | 
| 121 121 | 
             
                          case join
         | 
| 122 122 | 
             
                          when Hash, Symbol, Array
         | 
| 123 | 
            -
                             | 
| 124 | 
            -
                              other.klass, other.table, join
         | 
| 125 | 
            -
                            )
         | 
| 123 | 
            +
                            other.send(:construct_join_dependency, join)
         | 
| 126 124 | 
             
                          else
         | 
| 127 125 | 
             
                            join
         | 
| 128 126 | 
             
                          end
         | 
| @@ -141,9 +139,7 @@ module ActiveRecord | |
| 141 139 | 
             
                        joins_dependency = other.left_outer_joins_values.map do |join|
         | 
| 142 140 | 
             
                          case join
         | 
| 143 141 | 
             
                          when Hash, Symbol, Array
         | 
| 144 | 
            -
                             | 
| 145 | 
            -
                              other.klass, other.table, join
         | 
| 146 | 
            -
                            )
         | 
| 142 | 
            +
                            other.send(:construct_join_dependency, join)
         | 
| 147 143 | 
             
                          else
         | 
| 148 144 | 
             
                            join
         | 
| 149 145 | 
             
                          end
         | 
| @@ -27,7 +27,7 @@ module ActiveRecord | |
| 27 27 | 
             
                      key
         | 
| 28 28 | 
             
                    else
         | 
| 29 29 | 
             
                      key = key.to_s
         | 
| 30 | 
            -
                      key.split("." | 
| 30 | 
            +
                      key.split(".").first if key.include?(".")
         | 
| 31 31 | 
             
                    end
         | 
| 32 32 | 
             
                  end.compact
         | 
| 33 33 | 
             
                end
         | 
| @@ -62,9 +62,6 @@ module ActiveRecord | |
| 62 62 | 
             
                end
         | 
| 63 63 |  | 
| 64 64 | 
             
                protected
         | 
| 65 | 
            -
             | 
| 66 | 
            -
                  attr_reader :table
         | 
| 67 | 
            -
             | 
| 68 65 | 
             
                  def expand_from_hash(attributes)
         | 
| 69 66 | 
             
                    return ["1=0"] if attributes.empty?
         | 
| 70 67 |  | 
| @@ -115,6 +112,7 @@ module ActiveRecord | |
| 115 112 | 
             
                  end
         | 
| 116 113 |  | 
| 117 114 | 
             
                private
         | 
| 115 | 
            +
                  attr_reader :table
         | 
| 118 116 |  | 
| 119 117 | 
             
                  def associated_predicate_builder(association_name)
         | 
| 120 118 | 
             
                    self.class.new(table.associated_table(association_name))
         | 
| @@ -122,11 +120,11 @@ module ActiveRecord | |
| 122 120 |  | 
| 123 121 | 
             
                  def convert_dot_notation_to_hash(attributes)
         | 
| 124 122 | 
             
                    dot_notation = attributes.select do |k, v|
         | 
| 125 | 
            -
                      k.include?("." | 
| 123 | 
            +
                      k.include?(".") && !v.is_a?(Hash)
         | 
| 126 124 | 
             
                    end
         | 
| 127 125 |  | 
| 128 126 | 
             
                    dot_notation.each_key do |key|
         | 
| 129 | 
            -
                      table_name, column_name = key.split("." | 
| 127 | 
            +
                      table_name, column_name = key.split(".")
         | 
| 130 128 | 
             
                      value = attributes.delete(key)
         | 
| 131 129 | 
             
                      attributes[table_name] ||= {}
         | 
| 132 130 |  | 
| @@ -1,5 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require "active_support/core_ext/array/extract"
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            module ActiveRecord
         | 
| 4 6 | 
             
              class PredicateBuilder
         | 
| 5 7 | 
             
                class ArrayHandler # :nodoc:
         | 
| @@ -11,8 +13,8 @@ module ActiveRecord | |
| 11 13 | 
             
                    return attribute.in([]) if value.empty?
         | 
| 12 14 |  | 
| 13 15 | 
             
                    values = value.map { |x| x.is_a?(Base) ? x.id : x }
         | 
| 14 | 
            -
                    nils | 
| 15 | 
            -
                    ranges | 
| 16 | 
            +
                    nils = values.extract!(&:nil?)
         | 
| 17 | 
            +
                    ranges = values.extract! { |v| v.is_a?(Range) }
         | 
| 16 18 |  | 
| 17 19 | 
             
                    values_predicate =
         | 
| 18 20 | 
             
                      case values.length
         | 
| @@ -34,8 +36,7 @@ module ActiveRecord | |
| 34 36 | 
             
                    array_predicates.inject(&:or)
         | 
| 35 37 | 
             
                  end
         | 
| 36 38 |  | 
| 37 | 
            -
                   | 
| 38 | 
            -
             | 
| 39 | 
            +
                  private
         | 
| 39 40 | 
             
                    attr_reader :predicate_builder
         | 
| 40 41 |  | 
| 41 42 | 
             
                    module NullPredicate # :nodoc:
         | 
| @@ -12,12 +12,9 @@ module ActiveRecord | |
| 12 12 | 
             
                    [associated_table.association_join_foreign_key.to_s => ids]
         | 
| 13 13 | 
             
                  end
         | 
| 14 14 |  | 
| 15 | 
            -
                   | 
| 16 | 
            -
                  # Workaround for Ruby 2.2 "private attribute?" warning.
         | 
| 17 | 
            -
                  protected
         | 
| 15 | 
            +
                  private
         | 
| 18 16 | 
             
                    attr_reader :associated_table, :value
         | 
| 19 17 |  | 
| 20 | 
            -
                  private
         | 
| 21 18 | 
             
                    def ids
         | 
| 22 19 | 
             
                      case value
         | 
| 23 20 | 
             
                      when Relation
         |