activerecord 4.2.11.3 → 5.0.7.2
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 +1638 -1132
 - data/MIT-LICENSE +2 -2
 - data/README.rdoc +7 -8
 - data/examples/performance.rb +2 -3
 - data/examples/simple.rb +0 -1
 - data/lib/active_record.rb +7 -2
 - data/lib/active_record/aggregations.rb +34 -21
 - data/lib/active_record/association_relation.rb +7 -4
 - data/lib/active_record/associations.rb +347 -218
 - data/lib/active_record/associations/alias_tracker.rb +19 -16
 - data/lib/active_record/associations/association.rb +22 -10
 - data/lib/active_record/associations/association_scope.rb +75 -104
 - data/lib/active_record/associations/belongs_to_association.rb +21 -32
 - data/lib/active_record/associations/builder/association.rb +28 -34
 - data/lib/active_record/associations/builder/belongs_to.rb +43 -18
 - data/lib/active_record/associations/builder/collection_association.rb +7 -19
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +16 -11
 - data/lib/active_record/associations/builder/has_many.rb +4 -4
 - data/lib/active_record/associations/builder/has_one.rb +11 -6
 - data/lib/active_record/associations/builder/singular_association.rb +13 -11
 - data/lib/active_record/associations/collection_association.rb +85 -69
 - data/lib/active_record/associations/collection_proxy.rb +104 -46
 - data/lib/active_record/associations/foreign_association.rb +1 -1
 - data/lib/active_record/associations/has_many_association.rb +21 -78
 - data/lib/active_record/associations/has_many_through_association.rb +6 -47
 - data/lib/active_record/associations/has_one_association.rb +12 -5
 - data/lib/active_record/associations/join_dependency.rb +38 -22
 - data/lib/active_record/associations/join_dependency/join_association.rb +15 -14
 - data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
 - data/lib/active_record/associations/preloader.rb +14 -4
 - data/lib/active_record/associations/preloader/association.rb +52 -71
 - data/lib/active_record/associations/preloader/collection_association.rb +0 -7
 - data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
 - data/lib/active_record/associations/preloader/has_one.rb +0 -8
 - data/lib/active_record/associations/preloader/singular_association.rb +0 -1
 - data/lib/active_record/associations/preloader/through_association.rb +36 -17
 - data/lib/active_record/associations/singular_association.rb +13 -1
 - data/lib/active_record/associations/through_association.rb +12 -4
 - data/lib/active_record/attribute.rb +69 -19
 - data/lib/active_record/attribute/user_provided_default.rb +28 -0
 - data/lib/active_record/attribute_assignment.rb +19 -140
 - data/lib/active_record/attribute_decorators.rb +6 -5
 - data/lib/active_record/attribute_methods.rb +69 -44
 - data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
 - data/lib/active_record/attribute_methods/dirty.rb +46 -86
 - data/lib/active_record/attribute_methods/primary_key.rb +16 -3
 - data/lib/active_record/attribute_methods/query.rb +2 -2
 - data/lib/active_record/attribute_methods/read.rb +31 -59
 - data/lib/active_record/attribute_methods/serialization.rb +13 -16
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +61 -14
 - data/lib/active_record/attribute_methods/write.rb +13 -37
 - data/lib/active_record/attribute_mutation_tracker.rb +70 -0
 - data/lib/active_record/attribute_set.rb +32 -3
 - data/lib/active_record/attribute_set/builder.rb +42 -16
 - data/lib/active_record/attributes.rb +199 -81
 - data/lib/active_record/autosave_association.rb +54 -17
 - data/lib/active_record/base.rb +32 -23
 - data/lib/active_record/callbacks.rb +39 -43
 - data/lib/active_record/coders/json.rb +1 -1
 - data/lib/active_record/coders/yaml_column.rb +20 -8
 - data/lib/active_record/collection_cache_key.rb +50 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +467 -189
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +66 -62
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +39 -4
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +86 -13
 - data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +61 -39
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -188
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +72 -17
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +407 -156
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +51 -34
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +177 -71
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +433 -399
 - data/lib/active_record/connection_adapters/column.rb +28 -43
 - data/lib/active_record/connection_adapters/connection_specification.rb +15 -27
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
 - data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
 - data/lib/active_record/connection_adapters/mysql/database_statements.rb +108 -0
 - data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
 - data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +25 -166
 - data/lib/active_record/connection_adapters/postgresql/column.rb +33 -11
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +18 -72
 - data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
 - data/lib/active_record/connection_adapters/postgresql/oid/array.rb +37 -57
 - data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +3 -3
 - data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
 - data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +13 -3
 - data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
 - data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/range.rb +31 -17
 - data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +56 -19
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
 - data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
 - data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +250 -154
 - data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
 - data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +264 -170
 - data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
 - data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
 - data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
 - data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +151 -194
 - data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
 - data/lib/active_record/connection_handling.rb +37 -14
 - data/lib/active_record/core.rb +92 -108
 - data/lib/active_record/counter_cache.rb +13 -24
 - data/lib/active_record/dynamic_matchers.rb +1 -20
 - data/lib/active_record/enum.rb +116 -76
 - data/lib/active_record/errors.rb +87 -48
 - data/lib/active_record/explain.rb +20 -9
 - data/lib/active_record/explain_registry.rb +1 -1
 - data/lib/active_record/explain_subscriber.rb +1 -1
 - data/lib/active_record/fixture_set/file.rb +26 -5
 - data/lib/active_record/fixtures.rb +77 -41
 - data/lib/active_record/gem_version.rb +4 -4
 - data/lib/active_record/inheritance.rb +32 -40
 - data/lib/active_record/integration.rb +17 -14
 - data/lib/active_record/internal_metadata.rb +56 -0
 - data/lib/active_record/legacy_yaml_adapter.rb +18 -2
 - data/lib/active_record/locale/en.yml +3 -2
 - data/lib/active_record/locking/optimistic.rb +15 -15
 - data/lib/active_record/locking/pessimistic.rb +1 -1
 - data/lib/active_record/log_subscriber.rb +48 -24
 - data/lib/active_record/migration.rb +362 -111
 - data/lib/active_record/migration/command_recorder.rb +59 -18
 - data/lib/active_record/migration/compatibility.rb +126 -0
 - data/lib/active_record/model_schema.rb +270 -73
 - data/lib/active_record/nested_attributes.rb +58 -29
 - data/lib/active_record/no_touching.rb +4 -0
 - data/lib/active_record/null_relation.rb +16 -8
 - data/lib/active_record/persistence.rb +152 -90
 - data/lib/active_record/query_cache.rb +18 -23
 - data/lib/active_record/querying.rb +12 -11
 - data/lib/active_record/railtie.rb +23 -16
 - data/lib/active_record/railties/controller_runtime.rb +1 -1
 - data/lib/active_record/railties/databases.rake +52 -41
 - data/lib/active_record/readonly_attributes.rb +1 -1
 - data/lib/active_record/reflection.rb +302 -115
 - data/lib/active_record/relation.rb +187 -120
 - data/lib/active_record/relation/batches.rb +141 -36
 - data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
 - data/lib/active_record/relation/calculations.rb +92 -117
 - data/lib/active_record/relation/delegation.rb +8 -20
 - data/lib/active_record/relation/finder_methods.rb +173 -89
 - data/lib/active_record/relation/from_clause.rb +32 -0
 - data/lib/active_record/relation/merger.rb +16 -42
 - data/lib/active_record/relation/predicate_builder.rb +120 -107
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
 - data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
 - data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
 - data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
 - data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
 - data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
 - data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
 - data/lib/active_record/relation/query_attribute.rb +19 -0
 - data/lib/active_record/relation/query_methods.rb +308 -244
 - data/lib/active_record/relation/record_fetch_warning.rb +49 -0
 - data/lib/active_record/relation/spawn_methods.rb +4 -7
 - data/lib/active_record/relation/where_clause.rb +174 -0
 - data/lib/active_record/relation/where_clause_factory.rb +38 -0
 - data/lib/active_record/result.rb +11 -4
 - data/lib/active_record/runtime_registry.rb +1 -1
 - data/lib/active_record/sanitization.rb +105 -66
 - data/lib/active_record/schema.rb +26 -22
 - data/lib/active_record/schema_dumper.rb +54 -37
 - data/lib/active_record/schema_migration.rb +11 -14
 - data/lib/active_record/scoping.rb +34 -16
 - data/lib/active_record/scoping/default.rb +28 -10
 - data/lib/active_record/scoping/named.rb +59 -26
 - data/lib/active_record/secure_token.rb +38 -0
 - data/lib/active_record/serialization.rb +3 -5
 - data/lib/active_record/statement_cache.rb +17 -15
 - data/lib/active_record/store.rb +8 -3
 - data/lib/active_record/suppressor.rb +58 -0
 - data/lib/active_record/table_metadata.rb +69 -0
 - data/lib/active_record/tasks/database_tasks.rb +66 -49
 - data/lib/active_record/tasks/mysql_database_tasks.rb +6 -14
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +12 -3
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
 - data/lib/active_record/timestamp.rb +20 -9
 - data/lib/active_record/touch_later.rb +63 -0
 - data/lib/active_record/transactions.rb +139 -57
 - data/lib/active_record/type.rb +66 -17
 - data/lib/active_record/type/adapter_specific_registry.rb +130 -0
 - data/lib/active_record/type/date.rb +2 -45
 - data/lib/active_record/type/date_time.rb +2 -49
 - data/lib/active_record/type/internal/abstract_json.rb +33 -0
 - data/lib/active_record/type/internal/timezone.rb +15 -0
 - data/lib/active_record/type/serialized.rb +15 -14
 - data/lib/active_record/type/time.rb +10 -16
 - data/lib/active_record/type/type_map.rb +4 -4
 - data/lib/active_record/type_caster.rb +7 -0
 - data/lib/active_record/type_caster/connection.rb +29 -0
 - data/lib/active_record/type_caster/map.rb +19 -0
 - data/lib/active_record/validations.rb +33 -32
 - data/lib/active_record/validations/absence.rb +23 -0
 - data/lib/active_record/validations/associated.rb +10 -3
 - data/lib/active_record/validations/length.rb +24 -0
 - data/lib/active_record/validations/presence.rb +11 -12
 - data/lib/active_record/validations/uniqueness.rb +33 -33
 - data/lib/rails/generators/active_record/migration.rb +15 -0
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -5
 - data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
 - data/lib/rails/generators/active_record/migration/templates/migration.rb +8 -1
 - data/lib/rails/generators/active_record/model/model_generator.rb +33 -16
 - data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
 - data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
 - metadata +58 -34
 - data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
 - data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
 - data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
 - data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
 - data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
 - data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
 - data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
 - data/lib/active_record/serializers/xml_serializer.rb +0 -193
 - data/lib/active_record/type/big_integer.rb +0 -13
 - data/lib/active_record/type/binary.rb +0 -50
 - data/lib/active_record/type/boolean.rb +0 -31
 - data/lib/active_record/type/decimal.rb +0 -64
 - data/lib/active_record/type/decimal_without_scale.rb +0 -11
 - data/lib/active_record/type/decorator.rb +0 -14
 - data/lib/active_record/type/float.rb +0 -19
 - data/lib/active_record/type/integer.rb +0 -59
 - data/lib/active_record/type/mutable.rb +0 -16
 - data/lib/active_record/type/numeric.rb +0 -36
 - data/lib/active_record/type/string.rb +0 -40
 - data/lib/active_record/type/text.rb +0 -11
 - data/lib/active_record/type/time_value.rb +0 -38
 - data/lib/active_record/type/unsigned_integer.rb +0 -15
 - data/lib/active_record/type/value.rb +0 -110
 
| 
         @@ -1,15 +1,13 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'set'
         
     | 
| 
       2 
1 
     | 
    
         
             
            require 'active_support/concern'
         
     | 
| 
       3 
     | 
    
         
            -
            require 'active_support/deprecation'
         
     | 
| 
       4 
2 
     | 
    
         | 
| 
       5 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       6 
4 
     | 
    
         
             
              module Delegation # :nodoc:
         
     | 
| 
       7 
     | 
    
         
            -
                module DelegateCache
         
     | 
| 
       8 
     | 
    
         
            -
                  def relation_delegate_class(klass) 
     | 
| 
      
 5 
     | 
    
         
            +
                module DelegateCache # :nodoc:
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def relation_delegate_class(klass)
         
     | 
| 
       9 
7 
     | 
    
         
             
                    @relation_delegate_cache[klass]
         
     | 
| 
       10 
8 
     | 
    
         
             
                  end
         
     | 
| 
       11 
9 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                  def initialize_relation_delegate_cache 
     | 
| 
      
 10 
     | 
    
         
            +
                  def initialize_relation_delegate_cache
         
     | 
| 
       13 
11 
     | 
    
         
             
                    @relation_delegate_cache = cache = {}
         
     | 
| 
       14 
12 
     | 
    
         
             
                    [
         
     | 
| 
       15 
13 
     | 
    
         
             
                      ActiveRecord::Relation,
         
     | 
| 
         @@ -19,7 +17,7 @@ module ActiveRecord 
     | 
|
| 
       19 
17 
     | 
    
         
             
                      delegate = Class.new(klass) {
         
     | 
| 
       20 
18 
     | 
    
         
             
                        include ClassSpecificRelation
         
     | 
| 
       21 
19 
     | 
    
         
             
                      }
         
     | 
| 
       22 
     | 
    
         
            -
                      const_set klass.name.gsub('::', '_'), delegate
         
     | 
| 
      
 20 
     | 
    
         
            +
                      const_set klass.name.gsub('::'.freeze, '_'.freeze), delegate
         
     | 
| 
       23 
21 
     | 
    
         
             
                      cache[klass] = delegate
         
     | 
| 
       24 
22 
     | 
    
         
             
                    end
         
     | 
| 
       25 
23 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -37,13 +35,10 @@ module ActiveRecord 
     | 
|
| 
       37 
35 
     | 
    
         
             
                # may vary depending on the klass of a relation, so we create a subclass of Relation
         
     | 
| 
       38 
36 
     | 
    
         
             
                # for each different klass, and the delegations are compiled into that subclass only.
         
     | 
| 
       39 
37 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                 
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                ].to_set # :nodoc:
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join, to: :to_a
         
     | 
| 
      
 38 
     | 
    
         
            +
                delegate :to_xml, :encode_with, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join,
         
     | 
| 
      
 39 
     | 
    
         
            +
                         :[], :&, :|, :+, :-, :sample, :reverse, :compact, :in_groups, :in_groups_of,
         
     | 
| 
      
 40 
     | 
    
         
            +
                         :to_sentence, :to_formatted_s,
         
     | 
| 
      
 41 
     | 
    
         
            +
                         :shuffle, :split, :index, to: :records
         
     | 
| 
       47 
42 
     | 
    
         | 
| 
       48 
43 
     | 
    
         
             
                delegate :table_name, :quoted_table_name, :primary_key, :quoted_primary_key,
         
     | 
| 
       49 
44 
     | 
    
         
             
                         :connection, :columns_hash, :to => :klass
         
     | 
| 
         @@ -115,21 +110,14 @@ module ActiveRecord 
     | 
|
| 
       115 
110 
     | 
    
         | 
| 
       116 
111 
     | 
    
         
             
                def respond_to?(method, include_private = false)
         
     | 
| 
       117 
112 
     | 
    
         
             
                  super || @klass.respond_to?(method, include_private) ||
         
     | 
| 
       118 
     | 
    
         
            -
                    array_delegable?(method) ||
         
     | 
| 
       119 
113 
     | 
    
         
             
                    arel.respond_to?(method, include_private)
         
     | 
| 
       120 
114 
     | 
    
         
             
                end
         
     | 
| 
       121 
115 
     | 
    
         | 
| 
       122 
116 
     | 
    
         
             
                protected
         
     | 
| 
       123 
117 
     | 
    
         | 
| 
       124 
     | 
    
         
            -
                def array_delegable?(method)
         
     | 
| 
       125 
     | 
    
         
            -
                  Array.method_defined?(method) && BLACKLISTED_ARRAY_METHODS.exclude?(method)
         
     | 
| 
       126 
     | 
    
         
            -
                end
         
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
118 
     | 
    
         
             
                def method_missing(method, *args, &block)
         
     | 
| 
       129 
119 
     | 
    
         
             
                  if @klass.respond_to?(method)
         
     | 
| 
       130 
120 
     | 
    
         
             
                    scoping { @klass.public_send(method, *args, &block) }
         
     | 
| 
       131 
     | 
    
         
            -
                  elsif array_delegable?(method)
         
     | 
| 
       132 
     | 
    
         
            -
                    to_a.public_send(method, *args, &block)
         
     | 
| 
       133 
121 
     | 
    
         
             
                  elsif arel.respond_to?(method)
         
     | 
| 
       134 
122 
     | 
    
         
             
                    arel.public_send(method, *args, &block)
         
     | 
| 
       135 
123 
     | 
    
         
             
                  else
         
     | 
| 
         @@ -1,4 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'active_support/deprecation'
         
     | 
| 
       2 
1 
     | 
    
         
             
            require 'active_support/core_ext/string/filters'
         
     | 
| 
       3 
2 
     | 
    
         | 
| 
       4 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
         @@ -6,7 +5,7 @@ module ActiveRecord 
     | 
|
| 
       6 
5 
     | 
    
         
             
                ONE_AS_ONE = '1 AS one'
         
     | 
| 
       7 
6 
     | 
    
         | 
| 
       8 
7 
     | 
    
         
             
                # Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
         
     | 
| 
       9 
     | 
    
         
            -
                # If  
     | 
| 
      
 8 
     | 
    
         
            +
                # If one or more records can not be found for the requested ids, then RecordNotFound will be raised. If the primary key
         
     | 
| 
       10 
9 
     | 
    
         
             
                # is an integer, find by id coerces its arguments using +to_i+.
         
     | 
| 
       11 
10 
     | 
    
         
             
                #
         
     | 
| 
       12 
11 
     | 
    
         
             
                #   Person.find(1)          # returns the object for ID = 1
         
     | 
| 
         @@ -17,11 +16,9 @@ module ActiveRecord 
     | 
|
| 
       17 
16 
     | 
    
         
             
                #   Person.find([1])        # returns an array for the object with ID = 1
         
     | 
| 
       18 
17 
     | 
    
         
             
                #   Person.where("administrator = 1").order("created_on DESC").find(1)
         
     | 
| 
       19 
18 
     | 
    
         
             
                #
         
     | 
| 
       20 
     | 
    
         
            -
                # <tt>ActiveRecord::RecordNotFound</tt> will be raised if one or more ids are not found.
         
     | 
| 
       21 
     | 
    
         
            -
                #
         
     | 
| 
       22 
19 
     | 
    
         
             
                # NOTE: The returned records may not be in the same order as the ids you
         
     | 
| 
       23 
     | 
    
         
            -
                # provide since database rows are unordered. You 
     | 
| 
       24 
     | 
    
         
            -
                # option if you want the results  
     | 
| 
      
 20 
     | 
    
         
            +
                # provide since database rows are unordered. You will need to provide an explicit QueryMethods#order
         
     | 
| 
      
 21 
     | 
    
         
            +
                # option if you want the results to be sorted.
         
     | 
| 
       25 
22 
     | 
    
         
             
                #
         
     | 
| 
       26 
23 
     | 
    
         
             
                # ==== Find with lock
         
     | 
| 
       27 
24 
     | 
    
         
             
                #
         
     | 
| 
         @@ -37,7 +34,7 @@ module ActiveRecord 
     | 
|
| 
       37 
34 
     | 
    
         
             
                #     person.save!
         
     | 
| 
       38 
35 
     | 
    
         
             
                #   end
         
     | 
| 
       39 
36 
     | 
    
         
             
                #
         
     | 
| 
       40 
     | 
    
         
            -
                # ==== Variations of  
     | 
| 
      
 37 
     | 
    
         
            +
                # ==== Variations of #find
         
     | 
| 
       41 
38 
     | 
    
         
             
                #
         
     | 
| 
       42 
39 
     | 
    
         
             
                #   Person.where(name: 'Spartacus', rating: 4)
         
     | 
| 
       43 
40 
     | 
    
         
             
                #   # returns a chainable list (which can be empty).
         
     | 
| 
         @@ -45,13 +42,13 @@ module ActiveRecord 
     | 
|
| 
       45 
42 
     | 
    
         
             
                #   Person.find_by(name: 'Spartacus', rating: 4)
         
     | 
| 
       46 
43 
     | 
    
         
             
                #   # returns the first item or nil.
         
     | 
| 
       47 
44 
     | 
    
         
             
                #
         
     | 
| 
       48 
     | 
    
         
            -
                #   Person. 
     | 
| 
      
 45 
     | 
    
         
            +
                #   Person.find_or_initialize_by(name: 'Spartacus', rating: 4)
         
     | 
| 
       49 
46 
     | 
    
         
             
                #   # returns the first item or returns a new instance (requires you call .save to persist against the database).
         
     | 
| 
       50 
47 
     | 
    
         
             
                #
         
     | 
| 
       51 
     | 
    
         
            -
                #   Person. 
     | 
| 
       52 
     | 
    
         
            -
                #   # returns the first item or creates it and returns it 
     | 
| 
      
 48 
     | 
    
         
            +
                #   Person.find_or_create_by(name: 'Spartacus', rating: 4)
         
     | 
| 
      
 49 
     | 
    
         
            +
                #   # returns the first item or creates it and returns it.
         
     | 
| 
       53 
50 
     | 
    
         
             
                #
         
     | 
| 
       54 
     | 
    
         
            -
                # ==== Alternatives for  
     | 
| 
      
 51 
     | 
    
         
            +
                # ==== Alternatives for #find
         
     | 
| 
       55 
52 
     | 
    
         
             
                #
         
     | 
| 
       56 
53 
     | 
    
         
             
                #   Person.where(name: 'Spartacus', rating: 4).exists?(conditions = :none)
         
     | 
| 
       57 
54 
     | 
    
         
             
                #   # returns a boolean indicating if any record with the given conditions exist.
         
     | 
| 
         @@ -60,16 +57,13 @@ module ActiveRecord 
     | 
|
| 
       60 
57 
     | 
    
         
             
                #   # returns a chainable list of instances with only the mentioned fields.
         
     | 
| 
       61 
58 
     | 
    
         
             
                #
         
     | 
| 
       62 
59 
     | 
    
         
             
                #   Person.where(name: 'Spartacus', rating: 4).ids
         
     | 
| 
       63 
     | 
    
         
            -
                #   # returns an Array of ids 
     | 
| 
      
 60 
     | 
    
         
            +
                #   # returns an Array of ids.
         
     | 
| 
       64 
61 
     | 
    
         
             
                #
         
     | 
| 
       65 
62 
     | 
    
         
             
                #   Person.where(name: 'Spartacus', rating: 4).pluck(:field1, :field2)
         
     | 
| 
       66 
     | 
    
         
            -
                #   # returns an Array of the required fields 
     | 
| 
      
 63 
     | 
    
         
            +
                #   # returns an Array of the required fields.
         
     | 
| 
       67 
64 
     | 
    
         
             
                def find(*args)
         
     | 
| 
       68 
     | 
    
         
            -
                  if block_given?
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                  else
         
     | 
| 
       71 
     | 
    
         
            -
                    find_with_ids(*args)
         
     | 
| 
       72 
     | 
    
         
            -
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                  return super if block_given?
         
     | 
| 
      
 66 
     | 
    
         
            +
                  find_with_ids(*args)
         
     | 
| 
       73 
67 
     | 
    
         
             
                end
         
     | 
| 
       74 
68 
     | 
    
         | 
| 
       75 
69 
     | 
    
         
             
                # Finds the first record matching the specified conditions. There
         
     | 
| 
         @@ -80,18 +74,19 @@ module ActiveRecord 
     | 
|
| 
       80 
74 
     | 
    
         
             
                #
         
     | 
| 
       81 
75 
     | 
    
         
             
                #   Post.find_by name: 'Spartacus', rating: 4
         
     | 
| 
       82 
76 
     | 
    
         
             
                #   Post.find_by "published_at < ?", 2.weeks.ago
         
     | 
| 
       83 
     | 
    
         
            -
                def find_by(*args)
         
     | 
| 
       84 
     | 
    
         
            -
                  where(*args).take
         
     | 
| 
      
 77 
     | 
    
         
            +
                def find_by(arg, *args)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  where(arg, *args).take
         
     | 
| 
       85 
79 
     | 
    
         
             
                rescue RangeError
         
     | 
| 
       86 
80 
     | 
    
         
             
                  nil
         
     | 
| 
       87 
81 
     | 
    
         
             
                end
         
     | 
| 
       88 
82 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
                # Like  
     | 
| 
       90 
     | 
    
         
            -
                # an  
     | 
| 
       91 
     | 
    
         
            -
                def find_by!(*args)
         
     | 
| 
       92 
     | 
    
         
            -
                  where(*args).take!
         
     | 
| 
      
 83 
     | 
    
         
            +
                # Like #find_by, except that if no record is found, raises
         
     | 
| 
      
 84 
     | 
    
         
            +
                # an ActiveRecord::RecordNotFound error.
         
     | 
| 
      
 85 
     | 
    
         
            +
                def find_by!(arg, *args)
         
     | 
| 
      
 86 
     | 
    
         
            +
                  where(arg, *args).take!
         
     | 
| 
       93 
87 
     | 
    
         
             
                rescue RangeError
         
     | 
| 
       94 
     | 
    
         
            -
                  raise RecordNotFound 
     | 
| 
      
 88 
     | 
    
         
            +
                  raise RecordNotFound.new("Couldn't find #{@klass.name} with an out of range value",
         
     | 
| 
      
 89 
     | 
    
         
            +
                                           @klass.name)
         
     | 
| 
       95 
90 
     | 
    
         
             
                end
         
     | 
| 
       96 
91 
     | 
    
         | 
| 
       97 
92 
     | 
    
         
             
                # Gives a record (or N records if a parameter is supplied) without any implied
         
     | 
| 
         @@ -105,10 +100,10 @@ module ActiveRecord 
     | 
|
| 
       105 
100 
     | 
    
         
             
                  limit ? limit(limit).to_a : find_take
         
     | 
| 
       106 
101 
     | 
    
         
             
                end
         
     | 
| 
       107 
102 
     | 
    
         | 
| 
       108 
     | 
    
         
            -
                # Same as  
     | 
| 
       109 
     | 
    
         
            -
                # is found. Note that  
     | 
| 
      
 103 
     | 
    
         
            +
                # Same as #take but raises ActiveRecord::RecordNotFound if no record
         
     | 
| 
      
 104 
     | 
    
         
            +
                # is found. Note that #take! accepts no arguments.
         
     | 
| 
       110 
105 
     | 
    
         
             
                def take!
         
     | 
| 
       111 
     | 
    
         
            -
                  take or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql}]")
         
     | 
| 
      
 106 
     | 
    
         
            +
                  take or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql(@klass.arel_engine)}]")
         
     | 
| 
       112 
107 
     | 
    
         
             
                end
         
     | 
| 
       113 
108 
     | 
    
         | 
| 
       114 
109 
     | 
    
         
             
                # Find the first record (or first N records if a parameter is supplied).
         
     | 
| 
         @@ -122,14 +117,14 @@ module ActiveRecord 
     | 
|
| 
       122 
117 
     | 
    
         
             
                #
         
     | 
| 
       123 
118 
     | 
    
         
             
                def first(limit = nil)
         
     | 
| 
       124 
119 
     | 
    
         
             
                  if limit
         
     | 
| 
       125 
     | 
    
         
            -
                     
     | 
| 
      
 120 
     | 
    
         
            +
                    find_nth_with_limit_and_offset(0, limit, offset: offset_index)
         
     | 
| 
       126 
121 
     | 
    
         
             
                  else
         
     | 
| 
       127 
     | 
    
         
            -
                    find_nth 
     | 
| 
      
 122 
     | 
    
         
            +
                    find_nth 0
         
     | 
| 
       128 
123 
     | 
    
         
             
                  end
         
     | 
| 
       129 
124 
     | 
    
         
             
                end
         
     | 
| 
       130 
125 
     | 
    
         | 
| 
       131 
     | 
    
         
            -
                # Same as  
     | 
| 
       132 
     | 
    
         
            -
                # is found. Note that  
     | 
| 
      
 126 
     | 
    
         
            +
                # Same as #first but raises ActiveRecord::RecordNotFound if no record
         
     | 
| 
      
 127 
     | 
    
         
            +
                # is found. Note that #first! accepts no arguments.
         
     | 
| 
       133 
128 
     | 
    
         
             
                def first!
         
     | 
| 
       134 
129 
     | 
    
         
             
                  find_nth! 0
         
     | 
| 
       135 
130 
     | 
    
         
             
                end
         
     | 
| 
         @@ -150,21 +145,27 @@ module ActiveRecord 
     | 
|
| 
       150 
145 
     | 
    
         
             
                #
         
     | 
| 
       151 
146 
     | 
    
         
             
                #   [#<Person id:4>, #<Person id:3>, #<Person id:2>]
         
     | 
| 
       152 
147 
     | 
    
         
             
                def last(limit = nil)
         
     | 
| 
       153 
     | 
    
         
            -
                  if  
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
                   
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
                   
     | 
| 
      
 148 
     | 
    
         
            +
                  return find_last(limit) if loaded? || limit_value
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                  result = limit(limit || 1)
         
     | 
| 
      
 151 
     | 
    
         
            +
                  result.order!(arel_attribute(primary_key)) if order_values.empty? && primary_key
         
     | 
| 
      
 152 
     | 
    
         
            +
                  result = result.reverse_order!
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                  limit ? result.reverse : result.first
         
     | 
| 
      
 155 
     | 
    
         
            +
                rescue ActiveRecord::IrreversibleOrderError
         
     | 
| 
      
 156 
     | 
    
         
            +
                  ActiveSupport::Deprecation.warn(<<-WARNING.squish)
         
     | 
| 
      
 157 
     | 
    
         
            +
                      Finding a last element by loading the relation when SQL ORDER
         
     | 
| 
      
 158 
     | 
    
         
            +
                      can not be reversed is deprecated.
         
     | 
| 
      
 159 
     | 
    
         
            +
                      Rails 5.1 will raise ActiveRecord::IrreversibleOrderError in this case.
         
     | 
| 
      
 160 
     | 
    
         
            +
                      Please call `to_a.last` if you still want to load the relation.
         
     | 
| 
      
 161 
     | 
    
         
            +
                  WARNING
         
     | 
| 
      
 162 
     | 
    
         
            +
                  find_last(limit)
         
     | 
| 
       162 
163 
     | 
    
         
             
                end
         
     | 
| 
       163 
164 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
                # Same as  
     | 
| 
       165 
     | 
    
         
            -
                # is found. Note that  
     | 
| 
      
 165 
     | 
    
         
            +
                # Same as #last but raises ActiveRecord::RecordNotFound if no record
         
     | 
| 
      
 166 
     | 
    
         
            +
                # is found. Note that #last! accepts no arguments.
         
     | 
| 
       166 
167 
     | 
    
         
             
                def last!
         
     | 
| 
       167 
     | 
    
         
            -
                  last or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql}]")
         
     | 
| 
      
 168 
     | 
    
         
            +
                  last or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql(@klass.arel_engine)}]")
         
     | 
| 
       168 
169 
     | 
    
         
             
                end
         
     | 
| 
       169 
170 
     | 
    
         | 
| 
       170 
171 
     | 
    
         
             
                # Find the second record.
         
     | 
| 
         @@ -174,10 +175,10 @@ module ActiveRecord 
     | 
|
| 
       174 
175 
     | 
    
         
             
                #   Person.offset(3).second # returns the second object from OFFSET 3 (which is OFFSET 4)
         
     | 
| 
       175 
176 
     | 
    
         
             
                #   Person.where(["user_name = :u", { u: user_name }]).second
         
     | 
| 
       176 
177 
     | 
    
         
             
                def second
         
     | 
| 
       177 
     | 
    
         
            -
                  find_nth 
     | 
| 
      
 178 
     | 
    
         
            +
                  find_nth 1
         
     | 
| 
       178 
179 
     | 
    
         
             
                end
         
     | 
| 
       179 
180 
     | 
    
         | 
| 
       180 
     | 
    
         
            -
                # Same as  
     | 
| 
      
 181 
     | 
    
         
            +
                # Same as #second but raises ActiveRecord::RecordNotFound if no record
         
     | 
| 
       181 
182 
     | 
    
         
             
                # is found.
         
     | 
| 
       182 
183 
     | 
    
         
             
                def second!
         
     | 
| 
       183 
184 
     | 
    
         
             
                  find_nth! 1
         
     | 
| 
         @@ -190,10 +191,10 @@ module ActiveRecord 
     | 
|
| 
       190 
191 
     | 
    
         
             
                #   Person.offset(3).third # returns the third object from OFFSET 3 (which is OFFSET 5)
         
     | 
| 
       191 
192 
     | 
    
         
             
                #   Person.where(["user_name = :u", { u: user_name }]).third
         
     | 
| 
       192 
193 
     | 
    
         
             
                def third
         
     | 
| 
       193 
     | 
    
         
            -
                  find_nth 
     | 
| 
      
 194 
     | 
    
         
            +
                  find_nth 2
         
     | 
| 
       194 
195 
     | 
    
         
             
                end
         
     | 
| 
       195 
196 
     | 
    
         | 
| 
       196 
     | 
    
         
            -
                # Same as  
     | 
| 
      
 197 
     | 
    
         
            +
                # Same as #third but raises ActiveRecord::RecordNotFound if no record
         
     | 
| 
       197 
198 
     | 
    
         
             
                # is found.
         
     | 
| 
       198 
199 
     | 
    
         
             
                def third!
         
     | 
| 
       199 
200 
     | 
    
         
             
                  find_nth! 2
         
     | 
| 
         @@ -206,10 +207,10 @@ module ActiveRecord 
     | 
|
| 
       206 
207 
     | 
    
         
             
                #   Person.offset(3).fourth # returns the fourth object from OFFSET 3 (which is OFFSET 6)
         
     | 
| 
       207 
208 
     | 
    
         
             
                #   Person.where(["user_name = :u", { u: user_name }]).fourth
         
     | 
| 
       208 
209 
     | 
    
         
             
                def fourth
         
     | 
| 
       209 
     | 
    
         
            -
                  find_nth 
     | 
| 
      
 210 
     | 
    
         
            +
                  find_nth 3
         
     | 
| 
       210 
211 
     | 
    
         
             
                end
         
     | 
| 
       211 
212 
     | 
    
         | 
| 
       212 
     | 
    
         
            -
                # Same as  
     | 
| 
      
 213 
     | 
    
         
            +
                # Same as #fourth but raises ActiveRecord::RecordNotFound if no record
         
     | 
| 
       213 
214 
     | 
    
         
             
                # is found.
         
     | 
| 
       214 
215 
     | 
    
         
             
                def fourth!
         
     | 
| 
       215 
216 
     | 
    
         
             
                  find_nth! 3
         
     | 
| 
         @@ -222,10 +223,10 @@ module ActiveRecord 
     | 
|
| 
       222 
223 
     | 
    
         
             
                #   Person.offset(3).fifth # returns the fifth object from OFFSET 3 (which is OFFSET 7)
         
     | 
| 
       223 
224 
     | 
    
         
             
                #   Person.where(["user_name = :u", { u: user_name }]).fifth
         
     | 
| 
       224 
225 
     | 
    
         
             
                def fifth
         
     | 
| 
       225 
     | 
    
         
            -
                  find_nth 
     | 
| 
      
 226 
     | 
    
         
            +
                  find_nth 4
         
     | 
| 
       226 
227 
     | 
    
         
             
                end
         
     | 
| 
       227 
228 
     | 
    
         | 
| 
       228 
     | 
    
         
            -
                # Same as  
     | 
| 
      
 229 
     | 
    
         
            +
                # Same as #fifth but raises ActiveRecord::RecordNotFound if no record
         
     | 
| 
       229 
230 
     | 
    
         
             
                # is found.
         
     | 
| 
       230 
231 
     | 
    
         
             
                def fifth!
         
     | 
| 
       231 
232 
     | 
    
         
             
                  find_nth! 4
         
     | 
| 
         @@ -238,17 +239,49 @@ module ActiveRecord 
     | 
|
| 
       238 
239 
     | 
    
         
             
                #   Person.offset(3).forty_two # returns the forty-second object from OFFSET 3 (which is OFFSET 44)
         
     | 
| 
       239 
240 
     | 
    
         
             
                #   Person.where(["user_name = :u", { u: user_name }]).forty_two
         
     | 
| 
       240 
241 
     | 
    
         
             
                def forty_two
         
     | 
| 
       241 
     | 
    
         
            -
                  find_nth 
     | 
| 
      
 242 
     | 
    
         
            +
                  find_nth 41
         
     | 
| 
       242 
243 
     | 
    
         
             
                end
         
     | 
| 
       243 
244 
     | 
    
         | 
| 
       244 
     | 
    
         
            -
                # Same as  
     | 
| 
      
 245 
     | 
    
         
            +
                # Same as #forty_two but raises ActiveRecord::RecordNotFound if no record
         
     | 
| 
       245 
246 
     | 
    
         
             
                # is found.
         
     | 
| 
       246 
247 
     | 
    
         
             
                def forty_two!
         
     | 
| 
       247 
248 
     | 
    
         
             
                  find_nth! 41
         
     | 
| 
       248 
249 
     | 
    
         
             
                end
         
     | 
| 
       249 
250 
     | 
    
         | 
| 
       250 
     | 
    
         
            -
                #  
     | 
| 
       251 
     | 
    
         
            -
                #  
     | 
| 
      
 251 
     | 
    
         
            +
                # Find the third-to-last record.
         
     | 
| 
      
 252 
     | 
    
         
            +
                # If no order is defined it will order by primary key.
         
     | 
| 
      
 253 
     | 
    
         
            +
                #
         
     | 
| 
      
 254 
     | 
    
         
            +
                #   Person.third_to_last # returns the third-to-last object fetched by SELECT * FROM people
         
     | 
| 
      
 255 
     | 
    
         
            +
                #   Person.offset(3).third_to_last # returns the third-to-last object from OFFSET 3
         
     | 
| 
      
 256 
     | 
    
         
            +
                #   Person.where(["user_name = :u", { u: user_name }]).third_to_last
         
     | 
| 
      
 257 
     | 
    
         
            +
                def third_to_last
         
     | 
| 
      
 258 
     | 
    
         
            +
                  find_nth_from_last 3
         
     | 
| 
      
 259 
     | 
    
         
            +
                end
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
                # Same as #third_to_last but raises ActiveRecord::RecordNotFound if no record
         
     | 
| 
      
 262 
     | 
    
         
            +
                # is found.
         
     | 
| 
      
 263 
     | 
    
         
            +
                def third_to_last!
         
     | 
| 
      
 264 
     | 
    
         
            +
                  find_nth_from_last 3 or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql(@klass.arel_engine)}]")
         
     | 
| 
      
 265 
     | 
    
         
            +
                end
         
     | 
| 
      
 266 
     | 
    
         
            +
             
     | 
| 
      
 267 
     | 
    
         
            +
                # Find the second-to-last record.
         
     | 
| 
      
 268 
     | 
    
         
            +
                # If no order is defined it will order by primary key.
         
     | 
| 
      
 269 
     | 
    
         
            +
                #
         
     | 
| 
      
 270 
     | 
    
         
            +
                #   Person.second_to_last # returns the second-to-last object fetched by SELECT * FROM people
         
     | 
| 
      
 271 
     | 
    
         
            +
                #   Person.offset(3).second_to_last # returns the second-to-last object from OFFSET 3
         
     | 
| 
      
 272 
     | 
    
         
            +
                #   Person.where(["user_name = :u", { u: user_name }]).second_to_last
         
     | 
| 
      
 273 
     | 
    
         
            +
                def second_to_last
         
     | 
| 
      
 274 
     | 
    
         
            +
                  find_nth_from_last 2
         
     | 
| 
      
 275 
     | 
    
         
            +
                end
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
      
 277 
     | 
    
         
            +
                # Same as #second_to_last but raises ActiveRecord::RecordNotFound if no record
         
     | 
| 
      
 278 
     | 
    
         
            +
                # is found.
         
     | 
| 
      
 279 
     | 
    
         
            +
                def second_to_last!
         
     | 
| 
      
 280 
     | 
    
         
            +
                  find_nth_from_last 2 or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql(@klass.arel_engine)}]")
         
     | 
| 
      
 281 
     | 
    
         
            +
                end
         
     | 
| 
      
 282 
     | 
    
         
            +
             
     | 
| 
      
 283 
     | 
    
         
            +
                # Returns true if a record exists in the table that matches the +id+ or
         
     | 
| 
      
 284 
     | 
    
         
            +
                # conditions given, or false otherwise. The argument can take six forms:
         
     | 
| 
       252 
285 
     | 
    
         
             
                #
         
     | 
| 
       253 
286 
     | 
    
         
             
                # * Integer - Finds the record with this primary key.
         
     | 
| 
       254 
287 
     | 
    
         
             
                # * String - Finds the record with a primary key corresponding to this
         
     | 
| 
         @@ -261,7 +294,7 @@ module ActiveRecord 
     | 
|
| 
       261 
294 
     | 
    
         
             
                # * No args - Returns +false+ if the table is empty, +true+ otherwise.
         
     | 
| 
       262 
295 
     | 
    
         
             
                #
         
     | 
| 
       263 
296 
     | 
    
         
             
                # For more information about specifying conditions as a hash or array,
         
     | 
| 
       264 
     | 
    
         
            -
                # see the Conditions section in the introduction to  
     | 
| 
      
 297 
     | 
    
         
            +
                # see the Conditions section in the introduction to ActiveRecord::Base.
         
     | 
| 
       265 
298 
     | 
    
         
             
                #
         
     | 
| 
       266 
299 
     | 
    
         
             
                # Note: You can't pass in a condition as a string (like <tt>name =
         
     | 
| 
       267 
300 
     | 
    
         
             
                # 'Jamie'</tt>), since it would be sanitized and then queried against
         
     | 
| 
         @@ -279,7 +312,7 @@ module ActiveRecord 
     | 
|
| 
       279 
312 
     | 
    
         
             
                    conditions = conditions.id
         
     | 
| 
       280 
313 
     | 
    
         
             
                    ActiveSupport::Deprecation.warn(<<-MSG.squish)
         
     | 
| 
       281 
314 
     | 
    
         
             
                      You are passing an instance of ActiveRecord::Base to `exists?`.
         
     | 
| 
       282 
     | 
    
         
            -
                      Please pass the id of the object by calling `.id 
     | 
| 
      
 315 
     | 
    
         
            +
                      Please pass the id of the object by calling `.id`.
         
     | 
| 
       283 
316 
     | 
    
         
             
                    MSG
         
     | 
| 
       284 
317 
     | 
    
         
             
                  end
         
     | 
| 
       285 
318 
     | 
    
         | 
| 
         @@ -299,29 +332,31 @@ module ActiveRecord 
     | 
|
| 
       299 
332 
     | 
    
         
             
                    end
         
     | 
| 
       300 
333 
     | 
    
         
             
                  end
         
     | 
| 
       301 
334 
     | 
    
         | 
| 
       302 
     | 
    
         
            -
                  connection.select_value(relation, "#{name} Exists", relation. 
     | 
| 
      
 335 
     | 
    
         
            +
                  connection.select_value(relation, "#{name} Exists", relation.bound_attributes) ? true : false
         
     | 
| 
       303 
336 
     | 
    
         
             
                end
         
     | 
| 
       304 
337 
     | 
    
         | 
| 
       305 
338 
     | 
    
         
             
                # This method is called whenever no records are found with either a single
         
     | 
| 
       306 
     | 
    
         
            -
                # id or multiple ids and raises  
     | 
| 
      
 339 
     | 
    
         
            +
                # id or multiple ids and raises an ActiveRecord::RecordNotFound exception.
         
     | 
| 
       307 
340 
     | 
    
         
             
                #
         
     | 
| 
       308 
341 
     | 
    
         
             
                # The error message is different depending on whether a single id or
         
     | 
| 
       309 
342 
     | 
    
         
             
                # multiple ids are provided. If multiple ids are provided, then the number
         
     | 
| 
       310 
343 
     | 
    
         
             
                # of results obtained should be provided in the +result_size+ argument and
         
     | 
| 
       311 
344 
     | 
    
         
             
                # the expected number of results should be provided in the +expected_size+
         
     | 
| 
       312 
345 
     | 
    
         
             
                # argument.
         
     | 
| 
       313 
     | 
    
         
            -
                def raise_record_not_found_exception!(ids, result_size, expected_size) #:nodoc:
         
     | 
| 
       314 
     | 
    
         
            -
                  conditions = arel.where_sql
         
     | 
| 
      
 346 
     | 
    
         
            +
                def raise_record_not_found_exception!(ids, result_size, expected_size, key = primary_key) #:nodoc:
         
     | 
| 
      
 347 
     | 
    
         
            +
                  conditions = arel.where_sql(@klass.arel_engine)
         
     | 
| 
       315 
348 
     | 
    
         
             
                  conditions = " [#{conditions}]" if conditions
         
     | 
| 
      
 349 
     | 
    
         
            +
                  name = @klass.name
         
     | 
| 
       316 
350 
     | 
    
         | 
| 
       317 
351 
     | 
    
         
             
                  if Array(ids).size == 1
         
     | 
| 
       318 
     | 
    
         
            -
                    error = "Couldn't find #{ 
     | 
| 
      
 352 
     | 
    
         
            +
                    error = "Couldn't find #{name} with '#{key}'=#{ids}#{conditions}"
         
     | 
| 
      
 353 
     | 
    
         
            +
                    raise RecordNotFound.new(error, name, key, ids)
         
     | 
| 
       319 
354 
     | 
    
         
             
                  else
         
     | 
| 
       320 
     | 
    
         
            -
                    error = "Couldn't find all #{ 
     | 
| 
      
 355 
     | 
    
         
            +
                    error = "Couldn't find all #{name.pluralize} with '#{key}': "
         
     | 
| 
       321 
356 
     | 
    
         
             
                    error << "(#{ids.join(", ")})#{conditions} (found #{result_size} results, but was looking for #{expected_size})"
         
     | 
| 
       322 
     | 
    
         
            -
                  end
         
     | 
| 
       323 
357 
     | 
    
         | 
| 
       324 
     | 
    
         
            -
             
     | 
| 
      
 358 
     | 
    
         
            +
                    raise RecordNotFound, error
         
     | 
| 
      
 359 
     | 
    
         
            +
                  end
         
     | 
| 
       325 
360 
     | 
    
         
             
                end
         
     | 
| 
       326 
361 
     | 
    
         | 
| 
       327 
362 
     | 
    
         
             
                private
         
     | 
| 
         @@ -353,7 +388,7 @@ module ActiveRecord 
     | 
|
| 
       353 
388 
     | 
    
         
             
                      []
         
     | 
| 
       354 
389 
     | 
    
         
             
                    else
         
     | 
| 
       355 
390 
     | 
    
         
             
                      arel = relation.arel
         
     | 
| 
       356 
     | 
    
         
            -
                      rows = connection.select_all(arel, 'SQL',  
     | 
| 
      
 391 
     | 
    
         
            +
                      rows = connection.select_all(arel, 'SQL', relation.bound_attributes)
         
     | 
| 
       357 
392 
     | 
    
         
             
                      join_dependency.instantiate(rows, aliases)
         
     | 
| 
       358 
393 
     | 
    
         
             
                    end
         
     | 
| 
       359 
394 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -385,7 +420,7 @@ module ActiveRecord 
     | 
|
| 
       385 
420 
     | 
    
         
             
                  else
         
     | 
| 
       386 
421 
     | 
    
         
             
                    if relation.limit_value
         
     | 
| 
       387 
422 
     | 
    
         
             
                      limited_ids = limited_ids_for(relation)
         
     | 
| 
       388 
     | 
    
         
            -
                      limited_ids.empty? ? relation.none! : relation.where!( 
     | 
| 
      
 423 
     | 
    
         
            +
                      limited_ids.empty? ? relation.none! : relation.where!(primary_key => limited_ids)
         
     | 
| 
       389 
424 
     | 
    
         
             
                    end
         
     | 
| 
       390 
425 
     | 
    
         
             
                    relation.except(:limit, :offset)
         
     | 
| 
       391 
426 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -398,12 +433,12 @@ module ActiveRecord 
     | 
|
| 
       398 
433 
     | 
    
         
             
                  relation = relation.except(:select).select(values).distinct!
         
     | 
| 
       399 
434 
     | 
    
         
             
                  arel = relation.arel
         
     | 
| 
       400 
435 
     | 
    
         | 
| 
       401 
     | 
    
         
            -
                  id_rows = @klass.connection.select_all(arel, 'SQL',  
     | 
| 
      
 436 
     | 
    
         
            +
                  id_rows = @klass.connection.select_all(arel, 'SQL', relation.bound_attributes)
         
     | 
| 
       402 
437 
     | 
    
         
             
                  id_rows.map {|row| row[primary_key]}
         
     | 
| 
       403 
438 
     | 
    
         
             
                end
         
     | 
| 
       404 
439 
     | 
    
         | 
| 
       405 
440 
     | 
    
         
             
                def using_limitable_reflections?(reflections)
         
     | 
| 
       406 
     | 
    
         
            -
                  reflections.none? 
     | 
| 
      
 441 
     | 
    
         
            +
                  reflections.none?(&:collection?)
         
     | 
| 
       407 
442 
     | 
    
         
             
                end
         
     | 
| 
       408 
443 
     | 
    
         | 
| 
       409 
444 
     | 
    
         
             
                protected
         
     | 
| 
         @@ -434,7 +469,7 @@ module ActiveRecord 
     | 
|
| 
       434 
469 
     | 
    
         
             
                    id = id.id
         
     | 
| 
       435 
470 
     | 
    
         
             
                    ActiveSupport::Deprecation.warn(<<-MSG.squish)
         
     | 
| 
       436 
471 
     | 
    
         
             
                      You are passing an instance of ActiveRecord::Base to `find`.
         
     | 
| 
       437 
     | 
    
         
            -
                      Please pass the id of the object by calling `.id 
     | 
| 
      
 472 
     | 
    
         
            +
                      Please pass the id of the object by calling `.id`.
         
     | 
| 
       438 
473 
     | 
    
         
             
                    MSG
         
     | 
| 
       439 
474 
     | 
    
         
             
                  end
         
     | 
| 
       440 
475 
     | 
    
         | 
| 
         @@ -447,6 +482,8 @@ module ActiveRecord 
     | 
|
| 
       447 
482 
     | 
    
         
             
                end
         
     | 
| 
       448 
483 
     | 
    
         | 
| 
       449 
484 
     | 
    
         
             
                def find_some(ids)
         
     | 
| 
      
 485 
     | 
    
         
            +
                  return find_some_ordered(ids) unless order_values.present?
         
     | 
| 
      
 486 
     | 
    
         
            +
             
     | 
| 
       450 
487 
     | 
    
         
             
                  result = where(primary_key => ids).to_a
         
     | 
| 
       451 
488 
     | 
    
         | 
| 
       452 
489 
     | 
    
         
             
                  expected_size =
         
     | 
| 
         @@ -468,49 +505,96 @@ module ActiveRecord 
     | 
|
| 
       468 
505 
     | 
    
         
             
                  end
         
     | 
| 
       469 
506 
     | 
    
         
             
                end
         
     | 
| 
       470 
507 
     | 
    
         | 
| 
      
 508 
     | 
    
         
            +
                def find_some_ordered(ids)
         
     | 
| 
      
 509 
     | 
    
         
            +
                  ids = ids.slice(offset_value || 0, limit_value || ids.size) || []
         
     | 
| 
      
 510 
     | 
    
         
            +
             
     | 
| 
      
 511 
     | 
    
         
            +
                  result = except(:limit, :offset).where(primary_key => ids).records
         
     | 
| 
      
 512 
     | 
    
         
            +
             
     | 
| 
      
 513 
     | 
    
         
            +
                  if result.size == ids.size
         
     | 
| 
      
 514 
     | 
    
         
            +
                    pk_type = @klass.type_for_attribute(primary_key)
         
     | 
| 
      
 515 
     | 
    
         
            +
             
     | 
| 
      
 516 
     | 
    
         
            +
                    records_by_id = result.index_by(&:id)
         
     | 
| 
      
 517 
     | 
    
         
            +
                    ids.map { |id| records_by_id.fetch(pk_type.cast(id)) }
         
     | 
| 
      
 518 
     | 
    
         
            +
                  else
         
     | 
| 
      
 519 
     | 
    
         
            +
                    raise_record_not_found_exception!(ids, result.size, ids.size)
         
     | 
| 
      
 520 
     | 
    
         
            +
                  end
         
     | 
| 
      
 521 
     | 
    
         
            +
                end
         
     | 
| 
      
 522 
     | 
    
         
            +
             
     | 
| 
       471 
523 
     | 
    
         
             
                def find_take
         
     | 
| 
       472 
524 
     | 
    
         
             
                  if loaded?
         
     | 
| 
       473 
     | 
    
         
            -
                     
     | 
| 
      
 525 
     | 
    
         
            +
                    records.first
         
     | 
| 
       474 
526 
     | 
    
         
             
                  else
         
     | 
| 
       475 
     | 
    
         
            -
                    @take ||= limit(1). 
     | 
| 
      
 527 
     | 
    
         
            +
                    @take ||= limit(1).records.first
         
     | 
| 
       476 
528 
     | 
    
         
             
                  end
         
     | 
| 
       477 
529 
     | 
    
         
             
                end
         
     | 
| 
       478 
530 
     | 
    
         | 
| 
       479 
     | 
    
         
            -
                def find_nth(index, offset)
         
     | 
| 
      
 531 
     | 
    
         
            +
                def find_nth(index, offset = nil)
         
     | 
| 
      
 532 
     | 
    
         
            +
                  # TODO: once the offset argument is removed we rely on offset_index
         
     | 
| 
      
 533 
     | 
    
         
            +
                  # within find_nth_with_limit, rather than pass it in via
         
     | 
| 
      
 534 
     | 
    
         
            +
                  # find_nth_with_limit_and_offset
         
     | 
| 
      
 535 
     | 
    
         
            +
                  if offset
         
     | 
| 
      
 536 
     | 
    
         
            +
                    ActiveSupport::Deprecation.warn(<<-MSG.squish)
         
     | 
| 
      
 537 
     | 
    
         
            +
                      Passing an offset argument to find_nth is deprecated,
         
     | 
| 
      
 538 
     | 
    
         
            +
                      please use Relation#offset instead.
         
     | 
| 
      
 539 
     | 
    
         
            +
                    MSG
         
     | 
| 
      
 540 
     | 
    
         
            +
                  end
         
     | 
| 
       480 
541 
     | 
    
         
             
                  if loaded?
         
     | 
| 
       481 
     | 
    
         
            -
                     
     | 
| 
      
 542 
     | 
    
         
            +
                    records[index]
         
     | 
| 
       482 
543 
     | 
    
         
             
                  else
         
     | 
| 
       483 
     | 
    
         
            -
                    offset  
     | 
| 
       484 
     | 
    
         
            -
                    @offsets[offset] ||=  
     | 
| 
      
 544 
     | 
    
         
            +
                    offset ||= offset_index
         
     | 
| 
      
 545 
     | 
    
         
            +
                    @offsets[offset + index] ||= find_nth_with_limit_and_offset(index, 1, offset: offset).first
         
     | 
| 
       485 
546 
     | 
    
         
             
                  end
         
     | 
| 
       486 
547 
     | 
    
         
             
                end
         
     | 
| 
       487 
548 
     | 
    
         | 
| 
       488 
549 
     | 
    
         
             
                def find_nth!(index)
         
     | 
| 
       489 
     | 
    
         
            -
                  find_nth(index 
     | 
| 
      
 550 
     | 
    
         
            +
                  find_nth(index) or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql(@klass.arel_engine)}]")
         
     | 
| 
       490 
551 
     | 
    
         
             
                end
         
     | 
| 
       491 
552 
     | 
    
         | 
| 
       492 
     | 
    
         
            -
                def find_nth_with_limit( 
     | 
| 
      
 553 
     | 
    
         
            +
                def find_nth_with_limit(index, limit)
         
     | 
| 
      
 554 
     | 
    
         
            +
                  # TODO: once the offset argument is removed from find_nth,
         
     | 
| 
      
 555 
     | 
    
         
            +
                  # find_nth_with_limit_and_offset can be merged into this method
         
     | 
| 
       493 
556 
     | 
    
         
             
                  relation = if order_values.empty? && primary_key
         
     | 
| 
       494 
     | 
    
         
            -
                               order( 
     | 
| 
      
 557 
     | 
    
         
            +
                               order(arel_attribute(primary_key).asc)
         
     | 
| 
       495 
558 
     | 
    
         
             
                             else
         
     | 
| 
       496 
559 
     | 
    
         
             
                               self
         
     | 
| 
       497 
560 
     | 
    
         
             
                             end
         
     | 
| 
       498 
561 
     | 
    
         | 
| 
       499 
     | 
    
         
            -
                  relation = relation.offset( 
     | 
| 
      
 562 
     | 
    
         
            +
                  relation = relation.offset(index) unless index.zero?
         
     | 
| 
       500 
563 
     | 
    
         
             
                  relation.limit(limit).to_a
         
     | 
| 
       501 
564 
     | 
    
         
             
                end
         
     | 
| 
       502 
565 
     | 
    
         | 
| 
       503 
     | 
    
         
            -
                def  
     | 
| 
      
 566 
     | 
    
         
            +
                def find_nth_from_last(index)
         
     | 
| 
       504 
567 
     | 
    
         
             
                  if loaded?
         
     | 
| 
       505 
     | 
    
         
            -
                     
     | 
| 
      
 568 
     | 
    
         
            +
                    records[-index]
         
     | 
| 
       506 
569 
     | 
    
         
             
                  else
         
     | 
| 
       507 
     | 
    
         
            -
                     
     | 
| 
       508 
     | 
    
         
            -
             
     | 
| 
       509 
     | 
    
         
            -
             
     | 
| 
       510 
     | 
    
         
            -
             
     | 
| 
       511 
     | 
    
         
            -
             
     | 
| 
       512 
     | 
    
         
            -
             
     | 
| 
      
 570 
     | 
    
         
            +
                    relation = if order_values.empty? && primary_key
         
     | 
| 
      
 571 
     | 
    
         
            +
                                 order(arel_attribute(primary_key).asc)
         
     | 
| 
      
 572 
     | 
    
         
            +
                               else
         
     | 
| 
      
 573 
     | 
    
         
            +
                                 self
         
     | 
| 
      
 574 
     | 
    
         
            +
                               end
         
     | 
| 
      
 575 
     | 
    
         
            +
             
     | 
| 
      
 576 
     | 
    
         
            +
                    relation.to_a[-index]
         
     | 
| 
      
 577 
     | 
    
         
            +
                    # TODO: can be made more performant on large result sets by
         
     | 
| 
      
 578 
     | 
    
         
            +
                    # for instance, last(index)[-index] (which would require
         
     | 
| 
      
 579 
     | 
    
         
            +
                    # refactoring the last(n) finder method to make test suite pass),
         
     | 
| 
      
 580 
     | 
    
         
            +
                    # or by using a combination of reverse_order, limit, and offset,
         
     | 
| 
      
 581 
     | 
    
         
            +
                    # e.g., reverse_order.offset(index-1).first
         
     | 
| 
       513 
582 
     | 
    
         
             
                  end
         
     | 
| 
       514 
583 
     | 
    
         
             
                end
         
     | 
| 
      
 584 
     | 
    
         
            +
                
         
     | 
| 
      
 585 
     | 
    
         
            +
                private
         
     | 
| 
      
 586 
     | 
    
         
            +
             
     | 
| 
      
 587 
     | 
    
         
            +
                def find_nth_with_limit_and_offset(index, limit, offset:) # :nodoc:
         
     | 
| 
      
 588 
     | 
    
         
            +
                  if loaded?
         
     | 
| 
      
 589 
     | 
    
         
            +
                    records[index, limit]
         
     | 
| 
      
 590 
     | 
    
         
            +
                  else
         
     | 
| 
      
 591 
     | 
    
         
            +
                    index += offset
         
     | 
| 
      
 592 
     | 
    
         
            +
                    find_nth_with_limit(index, limit)
         
     | 
| 
      
 593 
     | 
    
         
            +
                  end
         
     | 
| 
      
 594 
     | 
    
         
            +
                end
         
     | 
| 
      
 595 
     | 
    
         
            +
             
     | 
| 
      
 596 
     | 
    
         
            +
                def find_last(limit)
         
     | 
| 
      
 597 
     | 
    
         
            +
                  limit ? records.last(limit) : records.last
         
     | 
| 
      
 598 
     | 
    
         
            +
                end
         
     | 
| 
       515 
599 
     | 
    
         
             
              end
         
     | 
| 
       516 
600 
     | 
    
         
             
            end
         
     |