activerecord 5.1.0 → 5.2.0.rc1
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 +5 -5
- data/CHANGELOG.md +410 -530
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -4
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record/aggregations.rb +6 -5
- data/lib/active_record/association_relation.rb +4 -2
- data/lib/active_record/associations/alias_tracker.rb +23 -32
- data/lib/active_record/associations/association.rb +20 -21
- data/lib/active_record/associations/association_scope.rb +49 -49
- data/lib/active_record/associations/belongs_to_association.rb +12 -10
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +4 -7
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +10 -6
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +2 -0
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +50 -41
- data/lib/active_record/associations/collection_proxy.rb +22 -39
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +4 -2
- data/lib/active_record/associations/has_many_through_association.rb +12 -18
- data/lib/active_record/associations/has_one_association.rb +5 -1
- data/lib/active_record/associations/has_one_through_association.rb +8 -7
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -64
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
- data/lib/active_record/associations/join_dependency.rb +27 -44
- data/lib/active_record/associations/preloader/association.rb +53 -92
- data/lib/active_record/associations/preloader/through_association.rb +72 -73
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +26 -11
- data/lib/active_record/associations.rb +68 -76
- data/lib/active_record/attribute_assignment.rb +2 -0
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +24 -214
- data/lib/active_record/attribute_methods/primary_key.rb +10 -13
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +8 -2
- data/lib/active_record/attribute_methods/serialization.rb +23 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
- data/lib/active_record/attribute_methods/write.rb +22 -19
- data/lib/active_record/attribute_methods.rb +48 -12
- data/lib/active_record/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +8 -11
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +8 -6
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +2 -0
- data/lib/active_record/collection_cache_key.rb +14 -10
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +175 -33
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +8 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -24
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +58 -3
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +165 -85
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +83 -97
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +118 -180
- data/lib/active_record/connection_adapters/column.rb +4 -2
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -17
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -23
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +269 -126
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +64 -85
- data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +92 -95
- data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
- data/lib/active_record/connection_handling.rb +4 -2
- data/lib/active_record/core.rb +39 -60
- data/lib/active_record/counter_cache.rb +3 -2
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +17 -13
- data/lib/active_record/errors.rb +42 -3
- data/lib/active_record/explain.rb +3 -1
- data/lib/active_record/explain_registry.rb +2 -0
- data/lib/active_record/explain_subscriber.rb +2 -0
- data/lib/active_record/fixture_set/file.rb +2 -0
- data/lib/active_record/fixtures.rb +67 -60
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +9 -9
- data/lib/active_record/integration.rb +58 -19
- data/lib/active_record/internal_metadata.rb +2 -0
- data/lib/active_record/legacy_yaml_adapter.rb +3 -1
- data/lib/active_record/locking/optimistic.rb +8 -6
- data/lib/active_record/locking/pessimistic.rb +9 -6
- data/lib/active_record/log_subscriber.rb +46 -4
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +74 -22
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/migration.rb +181 -137
- data/lib/active_record/model_schema.rb +73 -58
- data/lib/active_record/nested_attributes.rb +18 -6
- data/lib/active_record/no_touching.rb +3 -1
- data/lib/active_record/null_relation.rb +2 -0
- data/lib/active_record/persistence.rb +153 -18
- data/lib/active_record/query_cache.rb +17 -12
- data/lib/active_record/querying.rb +4 -2
- data/lib/active_record/railtie.rb +61 -3
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +2 -0
- data/lib/active_record/railties/databases.rake +47 -37
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +131 -204
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/batches.rb +32 -17
- data/lib/active_record/relation/calculations.rb +58 -20
- data/lib/active_record/relation/delegation.rb +10 -29
- data/lib/active_record/relation/finder_methods.rb +74 -85
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +51 -20
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +54 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/predicate_builder.rb +53 -78
- data/lib/active_record/relation/query_attribute.rb +9 -2
- data/lib/active_record/relation/query_methods.rb +101 -95
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +3 -1
- data/lib/active_record/relation/where_clause.rb +65 -67
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/relation.rb +99 -202
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +129 -121
- data/lib/active_record/schema.rb +4 -2
- data/lib/active_record/schema_dumper.rb +36 -26
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping/default.rb +10 -7
- data/lib/active_record/scoping/named.rb +38 -12
- data/lib/active_record/scoping.rb +12 -10
- data/lib/active_record/secure_token.rb +2 -0
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +22 -12
- data/lib/active_record/store.rb +3 -1
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +12 -3
- data/lib/active_record/tasks/database_tasks.rb +37 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
- data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +5 -5
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -7
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type/adapter_specific_registry.rb +2 -0
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +2 -0
- data/lib/active_record/type/text.rb +2 -0
- data/lib/active_record/type/time.rb +2 -0
- data/lib/active_record/type/type_map.rb +2 -0
- data/lib/active_record/type/unsigned_integer.rb +2 -0
- data/lib/active_record/type.rb +4 -1
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/type_caster.rb +2 -0
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +2 -0
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +2 -0
- data/lib/active_record/validations/uniqueness.rb +35 -5
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/version.rb +2 -0
- data/lib/active_record.rb +11 -4
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +2 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +3 -1
- metadata +25 -37
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -15
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -18
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute_mutation_tracker.rb +0 -113
- data/lib/active_record/attribute_set/builder.rb +0 -124
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
| @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module ActiveRecord
         | 
| 2 4 | 
             
              class Relation
         | 
| 3 5 | 
             
                class WhereClauseFactory # :nodoc:
         | 
| @@ -9,69 +11,24 @@ module ActiveRecord | |
| 9 11 | 
             
                  def build(opts, other)
         | 
| 10 12 | 
             
                    case opts
         | 
| 11 13 | 
             
                    when String, Array
         | 
| 12 | 
            -
                      parts = [klass. | 
| 14 | 
            +
                      parts = [klass.sanitize_sql(other.empty? ? opts : ([opts] + other))]
         | 
| 13 15 | 
             
                    when Hash
         | 
| 14 16 | 
             
                      attributes = predicate_builder.resolve_column_aliases(opts)
         | 
| 15 | 
            -
                      attributes = klass.send(:expand_hash_conditions_for_aggregates, attributes)
         | 
| 16 17 | 
             
                      attributes.stringify_keys!
         | 
| 17 18 |  | 
| 18 | 
            -
                       | 
| 19 | 
            -
                        parts, binds = build_for_case_sensitive(attributes, options)
         | 
| 20 | 
            -
                      else
         | 
| 21 | 
            -
                        attributes, binds = predicate_builder.create_binds(attributes)
         | 
| 22 | 
            -
                        parts = predicate_builder.build_from_hash(attributes)
         | 
| 23 | 
            -
                      end
         | 
| 19 | 
            +
                      parts = predicate_builder.build_from_hash(attributes)
         | 
| 24 20 | 
             
                    when Arel::Nodes::Node
         | 
| 25 21 | 
             
                      parts = [opts]
         | 
| 26 22 | 
             
                    else
         | 
| 27 23 | 
             
                      raise ArgumentError, "Unsupported argument type: #{opts} (#{opts.class})"
         | 
| 28 24 | 
             
                    end
         | 
| 29 25 |  | 
| 30 | 
            -
                    WhereClause.new(parts | 
| 26 | 
            +
                    WhereClause.new(parts)
         | 
| 31 27 | 
             
                  end
         | 
| 32 28 |  | 
| 33 | 
            -
                  # TODO Change this to private once we've dropped Ruby 2.2 support.
         | 
| 34 | 
            -
                  # Workaround for Ruby 2.2 "private attribute?" warning.
         | 
| 35 29 | 
             
                  protected
         | 
| 36 30 |  | 
| 37 31 | 
             
                    attr_reader :klass, :predicate_builder
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                  private
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                    def perform_case_sensitive?(options)
         | 
| 42 | 
            -
                      options && options.key?(:case_sensitive)
         | 
| 43 | 
            -
                    end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                    def build_for_case_sensitive(attributes, options)
         | 
| 46 | 
            -
                      parts, binds = [], []
         | 
| 47 | 
            -
                      table = klass.arel_table
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                      attributes.each do |attribute, value|
         | 
| 50 | 
            -
                        if reflection = klass._reflect_on_association(attribute)
         | 
| 51 | 
            -
                          attribute = reflection.foreign_key.to_s
         | 
| 52 | 
            -
                          value = value[reflection.klass.primary_key] unless value.nil?
         | 
| 53 | 
            -
                        end
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                        if value.nil?
         | 
| 56 | 
            -
                          parts << table[attribute].eq(value)
         | 
| 57 | 
            -
                        else
         | 
| 58 | 
            -
                          column = klass.column_for_attribute(attribute)
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                          binds << predicate_builder.send(:build_bind_param, attribute, value)
         | 
| 61 | 
            -
                          value = Arel::Nodes::BindParam.new
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                          predicate = if options[:case_sensitive]
         | 
| 64 | 
            -
                            klass.connection.case_sensitive_comparison(table, attribute, column, value)
         | 
| 65 | 
            -
                          else
         | 
| 66 | 
            -
                            klass.connection.case_insensitive_comparison(table, attribute, column, value)
         | 
| 67 | 
            -
                          end
         | 
| 68 | 
            -
             | 
| 69 | 
            -
                          parts << predicate
         | 
| 70 | 
            -
                        end
         | 
| 71 | 
            -
                      end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                      [parts, binds]
         | 
| 74 | 
            -
                    end
         | 
| 75 32 | 
             
                end
         | 
| 76 33 | 
             
              end
         | 
| 77 34 | 
             
            end
         | 
| @@ -1,14 +1,16 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module ActiveRecord
         | 
| 2 4 | 
             
              # = Active Record \Relation
         | 
| 3 5 | 
             
              class Relation
         | 
| 4 6 | 
             
                MULTI_VALUE_METHODS  = [:includes, :eager_load, :preload, :select, :group,
         | 
| 5 | 
            -
                                        :order, :joins, : | 
| 7 | 
            +
                                        :order, :joins, :left_outer_joins, :references,
         | 
| 6 8 | 
             
                                        :extending, :unscope]
         | 
| 7 9 |  | 
| 8 10 | 
             
                SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :reordering,
         | 
| 9 | 
            -
                                        :reverse_order, :distinct, :create_with]
         | 
| 11 | 
            +
                                        :reverse_order, :distinct, :create_with, :skip_query_cache]
         | 
| 10 12 | 
             
                CLAUSE_METHODS = [:where, :having, :from]
         | 
| 11 | 
            -
                INVALID_METHODS_FOR_DELETE_ALL = [: | 
| 13 | 
            +
                INVALID_METHODS_FOR_DELETE_ALL = [:distinct, :group, :having]
         | 
| 12 14 |  | 
| 13 15 | 
             
                VALUE_METHODS = MULTI_VALUE_METHODS + SINGLE_VALUE_METHODS + CLAUSE_METHODS
         | 
| 14 16 |  | 
| @@ -18,8 +20,9 @@ module ActiveRecord | |
| 18 20 | 
             
                attr_reader :table, :klass, :loaded, :predicate_builder
         | 
| 19 21 | 
             
                alias :model :klass
         | 
| 20 22 | 
             
                alias :loaded? :loaded
         | 
| 23 | 
            +
                alias :locked? :lock_value
         | 
| 21 24 |  | 
| 22 | 
            -
                def initialize(klass, table, predicate_builder, values  | 
| 25 | 
            +
                def initialize(klass, table: klass.arel_table, predicate_builder: klass.predicate_builder, values: {})
         | 
| 23 26 | 
             
                  @klass  = klass
         | 
| 24 27 | 
             
                  @table  = table
         | 
| 25 28 | 
             
                  @values = values
         | 
| @@ -33,74 +36,6 @@ module ActiveRecord | |
| 33 36 | 
             
                  reset
         | 
| 34 37 | 
             
                end
         | 
| 35 38 |  | 
| 36 | 
            -
                def insert(values) # :nodoc:
         | 
| 37 | 
            -
                  primary_key_value = nil
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                  if primary_key && Hash === values
         | 
| 40 | 
            -
                    primary_key_value = values[values.keys.find { |k|
         | 
| 41 | 
            -
                      k.name == primary_key
         | 
| 42 | 
            -
                    }]
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                    if !primary_key_value && klass.prefetch_primary_key?
         | 
| 45 | 
            -
                      primary_key_value = klass.next_sequence_value
         | 
| 46 | 
            -
                      values[arel_attribute(klass.primary_key)] = primary_key_value
         | 
| 47 | 
            -
                    end
         | 
| 48 | 
            -
                  end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                  im = arel.create_insert
         | 
| 51 | 
            -
                  im.into @table
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                  substitutes, binds = substitute_values values
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                  if values.empty? # empty insert
         | 
| 56 | 
            -
                    im.values = Arel.sql(connection.empty_insert_statement_value)
         | 
| 57 | 
            -
                  else
         | 
| 58 | 
            -
                    im.insert substitutes
         | 
| 59 | 
            -
                  end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                  @klass.connection.insert(
         | 
| 62 | 
            -
                    im,
         | 
| 63 | 
            -
                    "SQL",
         | 
| 64 | 
            -
                    primary_key || false,
         | 
| 65 | 
            -
                    primary_key_value,
         | 
| 66 | 
            -
                    nil,
         | 
| 67 | 
            -
                    binds)
         | 
| 68 | 
            -
                end
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                def _update_record(values, id, id_was) # :nodoc:
         | 
| 71 | 
            -
                  substitutes, binds = substitute_values values
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                  scope = @klass.unscoped
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                  if @klass.finder_needs_type_condition?
         | 
| 76 | 
            -
                    scope.unscope!(where: @klass.inheritance_column)
         | 
| 77 | 
            -
                  end
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                  relation = scope.where(@klass.primary_key => (id_was || id))
         | 
| 80 | 
            -
                  bvs = binds + relation.bound_attributes
         | 
| 81 | 
            -
                  um = relation
         | 
| 82 | 
            -
                    .arel
         | 
| 83 | 
            -
                    .compile_update(substitutes, @klass.primary_key)
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                  @klass.connection.update(
         | 
| 86 | 
            -
                    um,
         | 
| 87 | 
            -
                    "SQL",
         | 
| 88 | 
            -
                    bvs,
         | 
| 89 | 
            -
                  )
         | 
| 90 | 
            -
                end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                def substitute_values(values) # :nodoc:
         | 
| 93 | 
            -
                  binds = []
         | 
| 94 | 
            -
                  substitutes = []
         | 
| 95 | 
            -
             | 
| 96 | 
            -
                  values.each do |arel_attr, value|
         | 
| 97 | 
            -
                    binds.push QueryAttribute.new(arel_attr.name, value, klass.type_for_attribute(arel_attr.name))
         | 
| 98 | 
            -
                    substitutes.push [arel_attr, Arel::Nodes::BindParam.new]
         | 
| 99 | 
            -
                  end
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                  [substitutes, binds]
         | 
| 102 | 
            -
                end
         | 
| 103 | 
            -
             | 
| 104 39 | 
             
                def arel_attribute(name) # :nodoc:
         | 
| 105 40 | 
             
                  klass.arel_attribute(name, table)
         | 
| 106 41 | 
             
                end
         | 
| @@ -117,8 +52,8 @@ module ActiveRecord | |
| 117 52 | 
             
                #
         | 
| 118 53 | 
             
                #   user = users.new { |user| user.name = 'Oscar' }
         | 
| 119 54 | 
             
                #   user.name # => Oscar
         | 
| 120 | 
            -
                def new( | 
| 121 | 
            -
                  scoping {  | 
| 55 | 
            +
                def new(attributes = nil, &block)
         | 
| 56 | 
            +
                  scoping { klass.new(scope_for_create(attributes), &block) }
         | 
| 122 57 | 
             
                end
         | 
| 123 58 |  | 
| 124 59 | 
             
                alias build new
         | 
| @@ -142,8 +77,12 @@ module ActiveRecord | |
| 142 77 | 
             
                #
         | 
| 143 78 | 
             
                #   users.create(name: nil) # validation on name
         | 
| 144 79 | 
             
                #   # => #<User id: nil, name: nil, ...>
         | 
| 145 | 
            -
                def create( | 
| 146 | 
            -
                   | 
| 80 | 
            +
                def create(attributes = nil, &block)
         | 
| 81 | 
            +
                  if attributes.is_a?(Array)
         | 
| 82 | 
            +
                    attributes.collect { |attr| create(attr, &block) }
         | 
| 83 | 
            +
                  else
         | 
| 84 | 
            +
                    scoping { klass.create(scope_for_create(attributes), &block) }
         | 
| 85 | 
            +
                  end
         | 
| 147 86 | 
             
                end
         | 
| 148 87 |  | 
| 149 88 | 
             
                # Similar to #create, but calls
         | 
| @@ -152,8 +91,12 @@ module ActiveRecord | |
| 152 91 | 
             
                #
         | 
| 153 92 | 
             
                # Expects arguments in the same format as
         | 
| 154 93 | 
             
                # {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!].
         | 
| 155 | 
            -
                def create!( | 
| 156 | 
            -
                   | 
| 94 | 
            +
                def create!(attributes = nil, &block)
         | 
| 95 | 
            +
                  if attributes.is_a?(Array)
         | 
| 96 | 
            +
                    attributes.collect { |attr| create!(attr, &block) }
         | 
| 97 | 
            +
                  else
         | 
| 98 | 
            +
                    scoping { klass.create!(scope_for_create(attributes), &block) }
         | 
| 99 | 
            +
                  end
         | 
| 157 100 | 
             
                end
         | 
| 158 101 |  | 
| 159 102 | 
             
                def first_or_create(attributes = nil, &block) # :nodoc:
         | 
| @@ -247,9 +190,10 @@ module ActiveRecord | |
| 247 190 | 
             
                end
         | 
| 248 191 |  | 
| 249 192 | 
             
                # Converts relation objects to Array.
         | 
| 250 | 
            -
                def  | 
| 193 | 
            +
                def to_ary
         | 
| 251 194 | 
             
                  records.dup
         | 
| 252 195 | 
             
                end
         | 
| 196 | 
            +
                alias to_a to_ary
         | 
| 253 197 |  | 
| 254 198 | 
             
                def records # :nodoc:
         | 
| 255 199 | 
             
                  load
         | 
| @@ -269,8 +213,7 @@ module ActiveRecord | |
| 269 213 | 
             
                # Returns true if there are no records.
         | 
| 270 214 | 
             
                def empty?
         | 
| 271 215 | 
             
                  return @records.empty? if loaded?
         | 
| 272 | 
            -
             | 
| 273 | 
            -
                  limit_value == 0 || !exists?
         | 
| 216 | 
            +
                  !exists?
         | 
| 274 217 | 
             
                end
         | 
| 275 218 |  | 
| 276 219 | 
             
                # Returns true if there are no records.
         | 
| @@ -333,7 +276,7 @@ module ActiveRecord | |
| 333 276 | 
             
                # Please check unscoped if you want to remove all previous scopes (including
         | 
| 334 277 | 
             
                # the default_scope) during the execution of a block.
         | 
| 335 278 | 
             
                def scoping
         | 
| 336 | 
            -
                  previous, klass.current_scope = klass.current_scope, self
         | 
| 279 | 
            +
                  previous, klass.current_scope = klass.current_scope(true), self
         | 
| 337 280 | 
             
                  yield
         | 
| 338 281 | 
             
                ensure
         | 
| 339 282 | 
             
                  klass.current_scope = previous
         | 
| @@ -364,12 +307,17 @@ module ActiveRecord | |
| 364 307 | 
             
                def update_all(updates)
         | 
| 365 308 | 
             
                  raise ArgumentError, "Empty list of attributes to change" if updates.blank?
         | 
| 366 309 |  | 
| 310 | 
            +
                  if eager_loading?
         | 
| 311 | 
            +
                    relation = apply_join_dependency
         | 
| 312 | 
            +
                    return relation.update_all(updates)
         | 
| 313 | 
            +
                  end
         | 
| 314 | 
            +
             | 
| 367 315 | 
             
                  stmt = Arel::UpdateManager.new
         | 
| 368 316 |  | 
| 369 | 
            -
                  stmt.set Arel.sql(@klass. | 
| 317 | 
            +
                  stmt.set Arel.sql(@klass.sanitize_sql_for_assignment(updates))
         | 
| 370 318 | 
             
                  stmt.table(table)
         | 
| 371 319 |  | 
| 372 | 
            -
                  if has_join_values?
         | 
| 320 | 
            +
                  if has_join_values? || offset_value
         | 
| 373 321 | 
             
                    @klass.connection.join_to_update(stmt, arel, arel_attribute(primary_key))
         | 
| 374 322 | 
             
                  else
         | 
| 375 323 | 
             
                    stmt.key = arel_attribute(primary_key)
         | 
| @@ -378,51 +326,7 @@ module ActiveRecord | |
| 378 326 | 
             
                    stmt.wheres = arel.constraints
         | 
| 379 327 | 
             
                  end
         | 
| 380 328 |  | 
| 381 | 
            -
                  @klass.connection.update stmt, " | 
| 382 | 
            -
                end
         | 
| 383 | 
            -
             | 
| 384 | 
            -
                # Updates an object (or multiple objects) and saves it to the database, if validations pass.
         | 
| 385 | 
            -
                # The resulting object is returned whether the object was saved successfully to the database or not.
         | 
| 386 | 
            -
                #
         | 
| 387 | 
            -
                # ==== Parameters
         | 
| 388 | 
            -
                #
         | 
| 389 | 
            -
                # * +id+ - This should be the id or an array of ids to be updated.
         | 
| 390 | 
            -
                # * +attributes+ - This should be a hash of attributes or an array of hashes.
         | 
| 391 | 
            -
                #
         | 
| 392 | 
            -
                # ==== Examples
         | 
| 393 | 
            -
                #
         | 
| 394 | 
            -
                #   # Updates one record
         | 
| 395 | 
            -
                #   Person.update(15, user_name: 'Samuel', group: 'expert')
         | 
| 396 | 
            -
                #
         | 
| 397 | 
            -
                #   # Updates multiple records
         | 
| 398 | 
            -
                #   people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
         | 
| 399 | 
            -
                #   Person.update(people.keys, people.values)
         | 
| 400 | 
            -
                #
         | 
| 401 | 
            -
                #   # Updates multiple records from the result of a relation
         | 
| 402 | 
            -
                #   people = Person.where(group: 'expert')
         | 
| 403 | 
            -
                #   people.update(group: 'masters')
         | 
| 404 | 
            -
                #
         | 
| 405 | 
            -
                # Note: Updating a large number of records will run an
         | 
| 406 | 
            -
                # UPDATE query for each record, which may cause a performance
         | 
| 407 | 
            -
                # issue. So if it is not needed to run callbacks for each update, it is
         | 
| 408 | 
            -
                # preferred to use #update_all for updating all records using
         | 
| 409 | 
            -
                # a single query.
         | 
| 410 | 
            -
                def update(id = :all, attributes)
         | 
| 411 | 
            -
                  if id.is_a?(Array)
         | 
| 412 | 
            -
                    id.map.with_index { |one_id, idx| update(one_id, attributes[idx]) }
         | 
| 413 | 
            -
                  elsif id == :all
         | 
| 414 | 
            -
                    records.each { |record| record.update(attributes) }
         | 
| 415 | 
            -
                  else
         | 
| 416 | 
            -
                    if ActiveRecord::Base === id
         | 
| 417 | 
            -
                      raise ArgumentError, <<-MSG.squish
         | 
| 418 | 
            -
                        You are passing an instance of ActiveRecord::Base to `update`.
         | 
| 419 | 
            -
                        Please pass the id of the object by calling `.id`.
         | 
| 420 | 
            -
                      MSG
         | 
| 421 | 
            -
                    end
         | 
| 422 | 
            -
                    object = find(id)
         | 
| 423 | 
            -
                    object.update(attributes)
         | 
| 424 | 
            -
                    object
         | 
| 425 | 
            -
                  end
         | 
| 329 | 
            +
                  @klass.connection.update stmt, "#{@klass} Update All"
         | 
| 426 330 | 
             
                end
         | 
| 427 331 |  | 
| 428 332 | 
             
                # Destroys the records by instantiating each
         | 
| @@ -445,33 +349,6 @@ module ActiveRecord | |
| 445 349 | 
             
                  records.each(&:destroy).tap { reset }
         | 
| 446 350 | 
             
                end
         | 
| 447 351 |  | 
| 448 | 
            -
                # Destroy an object (or multiple objects) that has the given id. The object is instantiated first,
         | 
| 449 | 
            -
                # therefore all callbacks and filters are fired off before the object is deleted. This method is
         | 
| 450 | 
            -
                # less efficient than #delete but allows cleanup methods and other actions to be run.
         | 
| 451 | 
            -
                #
         | 
| 452 | 
            -
                # This essentially finds the object (or multiple objects) with the given id, creates a new object
         | 
| 453 | 
            -
                # from the attributes, and then calls destroy on it.
         | 
| 454 | 
            -
                #
         | 
| 455 | 
            -
                # ==== Parameters
         | 
| 456 | 
            -
                #
         | 
| 457 | 
            -
                # * +id+ - Can be either an Integer or an Array of Integers.
         | 
| 458 | 
            -
                #
         | 
| 459 | 
            -
                # ==== Examples
         | 
| 460 | 
            -
                #
         | 
| 461 | 
            -
                #   # Destroy a single object
         | 
| 462 | 
            -
                #   Todo.destroy(1)
         | 
| 463 | 
            -
                #
         | 
| 464 | 
            -
                #   # Destroy multiple objects
         | 
| 465 | 
            -
                #   todos = [1,2,3]
         | 
| 466 | 
            -
                #   Todo.destroy(todos)
         | 
| 467 | 
            -
                def destroy(id)
         | 
| 468 | 
            -
                  if id.is_a?(Array)
         | 
| 469 | 
            -
                    id.map { |one_id| destroy(one_id) }
         | 
| 470 | 
            -
                  else
         | 
| 471 | 
            -
                    find(id).destroy
         | 
| 472 | 
            -
                  end
         | 
| 473 | 
            -
                end
         | 
| 474 | 
            -
             | 
| 475 352 | 
             
                # Deletes the records without instantiating the records
         | 
| 476 353 | 
             
                # first, and hence not calling the {#destroy}[rdoc-ref:Persistence#destroy]
         | 
| 477 354 | 
             
                # method nor invoking callbacks.
         | 
| @@ -488,8 +365,8 @@ module ActiveRecord | |
| 488 365 | 
             
                #
         | 
| 489 366 | 
             
                # If an invalid method is supplied, #delete_all raises an ActiveRecordError:
         | 
| 490 367 | 
             
                #
         | 
| 491 | 
            -
                #   Post. | 
| 492 | 
            -
                #   # => ActiveRecord::ActiveRecordError: delete_all doesn't support  | 
| 368 | 
            +
                #   Post.distinct.delete_all
         | 
| 369 | 
            +
                #   # => ActiveRecord::ActiveRecordError: delete_all doesn't support distinct
         | 
| 493 370 | 
             
                def delete_all
         | 
| 494 371 | 
             
                  invalid_methods = INVALID_METHODS_FOR_DELETE_ALL.select do |method|
         | 
| 495 372 | 
             
                    value = get_value(method)
         | 
| @@ -499,44 +376,26 @@ module ActiveRecord | |
| 499 376 | 
             
                    raise ActiveRecordError.new("delete_all doesn't support #{invalid_methods.join(', ')}")
         | 
| 500 377 | 
             
                  end
         | 
| 501 378 |  | 
| 379 | 
            +
                  if eager_loading?
         | 
| 380 | 
            +
                    relation = apply_join_dependency
         | 
| 381 | 
            +
                    return relation.delete_all
         | 
| 382 | 
            +
                  end
         | 
| 383 | 
            +
             | 
| 502 384 | 
             
                  stmt = Arel::DeleteManager.new
         | 
| 503 385 | 
             
                  stmt.from(table)
         | 
| 504 386 |  | 
| 505 | 
            -
                  if has_join_values?
         | 
| 387 | 
            +
                  if has_join_values? || has_limit_or_offset?
         | 
| 506 388 | 
             
                    @klass.connection.join_to_delete(stmt, arel, arel_attribute(primary_key))
         | 
| 507 389 | 
             
                  else
         | 
| 508 390 | 
             
                    stmt.wheres = arel.constraints
         | 
| 509 391 | 
             
                  end
         | 
| 510 392 |  | 
| 511 | 
            -
                  affected = @klass.connection.delete(stmt, " | 
| 393 | 
            +
                  affected = @klass.connection.delete(stmt, "#{@klass} Destroy")
         | 
| 512 394 |  | 
| 513 395 | 
             
                  reset
         | 
| 514 396 | 
             
                  affected
         | 
| 515 397 | 
             
                end
         | 
| 516 398 |  | 
| 517 | 
            -
                # Deletes the row with a primary key matching the +id+ argument, using a
         | 
| 518 | 
            -
                # SQL +DELETE+ statement, and returns the number of rows deleted. Active
         | 
| 519 | 
            -
                # Record objects are not instantiated, so the object's callbacks are not
         | 
| 520 | 
            -
                # executed, including any <tt>:dependent</tt> association options.
         | 
| 521 | 
            -
                #
         | 
| 522 | 
            -
                # You can delete multiple rows at once by passing an Array of <tt>id</tt>s.
         | 
| 523 | 
            -
                #
         | 
| 524 | 
            -
                # Note: Although it is often much faster than the alternative,
         | 
| 525 | 
            -
                # #destroy, skipping callbacks might bypass business logic in
         | 
| 526 | 
            -
                # your application that ensures referential integrity or performs other
         | 
| 527 | 
            -
                # essential jobs.
         | 
| 528 | 
            -
                #
         | 
| 529 | 
            -
                # ==== Examples
         | 
| 530 | 
            -
                #
         | 
| 531 | 
            -
                #   # Delete a single row
         | 
| 532 | 
            -
                #   Todo.delete(1)
         | 
| 533 | 
            -
                #
         | 
| 534 | 
            -
                #   # Delete multiple rows
         | 
| 535 | 
            -
                #   Todo.delete([2,3,4])
         | 
| 536 | 
            -
                def delete(id_or_array)
         | 
| 537 | 
            -
                  where(primary_key => id_or_array).delete_all
         | 
| 538 | 
            -
                end
         | 
| 539 | 
            -
             | 
| 540 399 | 
             
                # Causes the records to be loaded from the database if they have not
         | 
| 541 400 | 
             
                # been loaded already. You can use this if for some reason you need
         | 
| 542 401 | 
             
                # to explicitly load some records before actually using them. The
         | 
| @@ -556,8 +415,7 @@ module ActiveRecord | |
| 556 415 | 
             
                end
         | 
| 557 416 |  | 
| 558 417 | 
             
                def reset
         | 
| 559 | 
            -
                  @ | 
| 560 | 
            -
                  @should_eager_load = @join_dependency = nil
         | 
| 418 | 
            +
                  @to_sql = @arel = @loaded = @should_eager_load = nil
         | 
| 561 419 | 
             
                  @records = [].freeze
         | 
| 562 420 | 
             
                  @offsets = {}
         | 
| 563 421 | 
             
                  self
         | 
| @@ -572,12 +430,12 @@ module ActiveRecord | |
| 572 430 | 
             
                                relation = self
         | 
| 573 431 |  | 
| 574 432 | 
             
                                if eager_loading?
         | 
| 575 | 
            -
                                   | 
| 433 | 
            +
                                  apply_join_dependency { |rel, _| relation = rel }
         | 
| 576 434 | 
             
                                end
         | 
| 577 435 |  | 
| 578 436 | 
             
                                conn = klass.connection
         | 
| 579 437 | 
             
                                conn.unprepared_statement {
         | 
| 580 | 
            -
                                  conn.to_sql(relation.arel | 
| 438 | 
            +
                                  conn.to_sql(relation.arel)
         | 
| 581 439 | 
             
                                }
         | 
| 582 440 | 
             
                              end
         | 
| 583 441 | 
             
                end
         | 
| @@ -586,12 +444,14 @@ module ActiveRecord | |
| 586 444 | 
             
                #
         | 
| 587 445 | 
             
                #   User.where(name: 'Oscar').where_values_hash
         | 
| 588 446 | 
             
                #   # => {name: "Oscar"}
         | 
| 589 | 
            -
                def where_values_hash(relation_table_name = table_name)
         | 
| 447 | 
            +
                def where_values_hash(relation_table_name = klass.table_name)
         | 
| 590 448 | 
             
                  where_clause.to_h(relation_table_name)
         | 
| 591 449 | 
             
                end
         | 
| 592 450 |  | 
| 593 | 
            -
                def scope_for_create
         | 
| 594 | 
            -
                   | 
| 451 | 
            +
                def scope_for_create(attributes = nil)
         | 
| 452 | 
            +
                  scope = where_values_hash.merge!(create_with_value.stringify_keys)
         | 
| 453 | 
            +
                  scope.merge!(attributes) if attributes
         | 
| 454 | 
            +
                  scope
         | 
| 595 455 | 
             
                end
         | 
| 596 456 |  | 
| 597 457 | 
             
                # Returns true if relation needs eager loading.
         | 
| @@ -643,6 +503,19 @@ module ActiveRecord | |
| 643 503 | 
             
                  "#<#{self.class.name} [#{entries.join(', ')}]>"
         | 
| 644 504 | 
             
                end
         | 
| 645 505 |  | 
| 506 | 
            +
                def empty_scope? # :nodoc:
         | 
| 507 | 
            +
                  @values == klass.unscoped.values
         | 
| 508 | 
            +
                end
         | 
| 509 | 
            +
             | 
| 510 | 
            +
                def has_limit_or_offset? # :nodoc:
         | 
| 511 | 
            +
                  limit_value || offset_value
         | 
| 512 | 
            +
                end
         | 
| 513 | 
            +
             | 
| 514 | 
            +
                def alias_tracker(joins = [], aliases = nil) # :nodoc:
         | 
| 515 | 
            +
                  joins += [aliases] if aliases
         | 
| 516 | 
            +
                  ActiveRecord::Associations::AliasTracker.create(connection, table.name, joins)
         | 
| 517 | 
            +
                end
         | 
| 518 | 
            +
             | 
| 646 519 | 
             
                protected
         | 
| 647 520 |  | 
| 648 521 | 
             
                  def load_records(records)
         | 
| @@ -657,20 +530,44 @@ module ActiveRecord | |
| 657 530 | 
             
                  end
         | 
| 658 531 |  | 
| 659 532 | 
             
                  def exec_queries(&block)
         | 
| 660 | 
            -
                     | 
| 661 | 
            -
             | 
| 662 | 
            -
             | 
| 663 | 
            -
             | 
| 664 | 
            -
             | 
| 665 | 
            -
             | 
| 666 | 
            -
             | 
| 667 | 
            -
             | 
| 668 | 
            -
             | 
| 533 | 
            +
                    skip_query_cache_if_necessary do
         | 
| 534 | 
            +
                      @records =
         | 
| 535 | 
            +
                        if eager_loading?
         | 
| 536 | 
            +
                          apply_join_dependency do |relation, join_dependency|
         | 
| 537 | 
            +
                            if ActiveRecord::NullRelation === relation
         | 
| 538 | 
            +
                              []
         | 
| 539 | 
            +
                            else
         | 
| 540 | 
            +
                              rows = connection.select_all(relation.arel, "SQL")
         | 
| 541 | 
            +
                              join_dependency.instantiate(rows, &block)
         | 
| 542 | 
            +
                            end.freeze
         | 
| 543 | 
            +
                          end
         | 
| 544 | 
            +
                        else
         | 
| 545 | 
            +
                          klass.find_by_sql(arel, &block).freeze
         | 
| 546 | 
            +
                        end
         | 
| 547 | 
            +
             | 
| 548 | 
            +
                      preload = preload_values
         | 
| 549 | 
            +
                      preload += includes_values unless eager_loading?
         | 
| 550 | 
            +
                      preloader = nil
         | 
| 551 | 
            +
                      preload.each do |associations|
         | 
| 552 | 
            +
                        preloader ||= build_preloader
         | 
| 553 | 
            +
                        preloader.preload @records, associations
         | 
| 554 | 
            +
                      end
         | 
| 669 555 |  | 
| 670 | 
            -
             | 
| 556 | 
            +
                      @records.each(&:readonly!) if readonly_value
         | 
| 671 557 |  | 
| 672 | 
            -
             | 
| 673 | 
            -
             | 
| 558 | 
            +
                      @loaded = true
         | 
| 559 | 
            +
                      @records
         | 
| 560 | 
            +
                    end
         | 
| 561 | 
            +
                  end
         | 
| 562 | 
            +
             | 
| 563 | 
            +
                  def skip_query_cache_if_necessary
         | 
| 564 | 
            +
                    if skip_query_cache_value
         | 
| 565 | 
            +
                      uncached do
         | 
| 566 | 
            +
                        yield
         | 
| 567 | 
            +
                      end
         | 
| 568 | 
            +
                    else
         | 
| 569 | 
            +
                      yield
         | 
| 570 | 
            +
                    end
         | 
| 674 571 | 
             
                  end
         | 
| 675 572 |  | 
| 676 573 | 
             
                  def build_preloader
         | 
    
        data/lib/active_record/result.rb
    CHANGED