activerecord 4.2.0 → 5.2.8.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +640 -928
- data/MIT-LICENSE +2 -2
- data/README.rdoc +10 -11
- data/examples/performance.rb +32 -31
- data/examples/simple.rb +5 -4
- data/lib/active_record/aggregations.rb +264 -247
- data/lib/active_record/association_relation.rb +24 -6
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +87 -41
- data/lib/active_record/associations/association_scope.rb +106 -132
- data/lib/active_record/associations/belongs_to_association.rb +55 -36
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +29 -38
- data/lib/active_record/associations/builder/belongs_to.rb +77 -30
- data/lib/active_record/associations/builder/collection_association.rb +14 -23
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +50 -39
- data/lib/active_record/associations/builder/has_many.rb +6 -4
- data/lib/active_record/associations/builder/has_one.rb +13 -6
- data/lib/active_record/associations/builder/singular_association.rb +15 -11
- data/lib/active_record/associations/collection_association.rb +145 -266
- data/lib/active_record/associations/collection_proxy.rb +242 -138
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +35 -75
- data/lib/active_record/associations/has_many_through_association.rb +51 -69
- data/lib/active_record/associations/has_one_association.rb +39 -24
- data/lib/active_record/associations/has_one_through_association.rb +18 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +40 -81
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
- data/lib/active_record/associations/join_dependency.rb +134 -154
- data/lib/active_record/associations/preloader/association.rb +85 -116
- data/lib/active_record/associations/preloader/through_association.rb +85 -74
- data/lib/active_record/associations/preloader.rb +83 -93
- data/lib/active_record/associations/singular_association.rb +27 -40
- data/lib/active_record/associations/through_association.rb +48 -23
- data/lib/active_record/associations.rb +1732 -1596
- data/lib/active_record/attribute_assignment.rb +58 -182
- data/lib/active_record/attribute_decorators.rb +39 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -5
- data/lib/active_record/attribute_methods/dirty.rb +94 -125
- data/lib/active_record/attribute_methods/primary_key.rb +86 -71
- data/lib/active_record/attribute_methods/query.rb +4 -2
- data/lib/active_record/attribute_methods/read.rb +45 -63
- data/lib/active_record/attribute_methods/serialization.rb +40 -20
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
- data/lib/active_record/attribute_methods/write.rb +31 -46
- data/lib/active_record/attribute_methods.rb +170 -117
- data/lib/active_record/attributes.rb +201 -74
- data/lib/active_record/autosave_association.rb +118 -45
- data/lib/active_record/base.rb +60 -48
- data/lib/active_record/callbacks.rb +97 -57
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +37 -13
- data/lib/active_record/collection_cache_key.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +712 -284
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +10 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +254 -87
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +72 -22
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -52
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +67 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -217
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +81 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +617 -212
- data/lib/active_record/connection_adapters/abstract/transaction.rb +139 -75
- data/lib/active_record/connection_adapters/abstract_adapter.rb +332 -191
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +567 -563
- data/lib/active_record/connection_adapters/column.rb +50 -41
- data/lib/active_record/connection_adapters/connection_specification.rb +147 -135
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +33 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +140 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +73 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +87 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +80 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +148 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +35 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +42 -195
- data/lib/active_record/connection_adapters/postgresql/column.rb +35 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -115
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
- 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 +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +65 -51
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +107 -47
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +144 -90
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +466 -280
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +39 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +439 -330
- data/lib/active_record/connection_adapters/schema_cache.rb +48 -24
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +34 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +67 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +106 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +269 -324
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +40 -27
- data/lib/active_record/core.rb +205 -202
- data/lib/active_record/counter_cache.rb +80 -37
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -105
- data/lib/active_record/enum.rb +136 -90
- data/lib/active_record/errors.rb +180 -52
- data/lib/active_record/explain.rb +23 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +11 -6
- data/lib/active_record/fixture_set/file.rb +35 -9
- data/lib/active_record/fixtures.rb +193 -135
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +148 -112
- data/lib/active_record/integration.rb +70 -28
- data/lib/active_record/internal_metadata.rb +45 -0
- data/lib/active_record/legacy_yaml_adapter.rb +48 -0
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +92 -98
- data/lib/active_record/locking/pessimistic.rb +15 -3
- data/lib/active_record/log_subscriber.rb +95 -33
- data/lib/active_record/migration/command_recorder.rb +133 -90
- data/lib/active_record/migration/compatibility.rb +217 -0
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +594 -267
- data/lib/active_record/model_schema.rb +292 -111
- data/lib/active_record/nested_attributes.rb +266 -214
- data/lib/active_record/no_touching.rb +8 -2
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +350 -119
- data/lib/active_record/query_cache.rb +13 -24
- data/lib/active_record/querying.rb +19 -17
- data/lib/active_record/railtie.rb +117 -35
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +9 -3
- data/lib/active_record/railties/databases.rake +160 -174
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +447 -288
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +204 -55
- data/lib/active_record/relation/calculations.rb +259 -244
- data/lib/active_record/relation/delegation.rb +67 -60
- data/lib/active_record/relation/finder_methods.rb +290 -253
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +91 -68
- data/lib/active_record/relation/predicate_builder/array_handler.rb +24 -23
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +20 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +42 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/predicate_builder.rb +118 -92
- data/lib/active_record/relation/query_attribute.rb +45 -0
- data/lib/active_record/relation/query_methods.rb +446 -389
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +18 -16
- data/lib/active_record/relation/where_clause.rb +186 -0
- data/lib/active_record/relation/where_clause_factory.rb +34 -0
- data/lib/active_record/relation.rb +287 -339
- data/lib/active_record/result.rb +54 -36
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +155 -124
- data/lib/active_record/schema.rb +30 -24
- data/lib/active_record/schema_dumper.rb +91 -87
- data/lib/active_record/schema_migration.rb +19 -19
- data/lib/active_record/scoping/default.rb +102 -84
- data/lib/active_record/scoping/named.rb +81 -32
- data/lib/active_record/scoping.rb +45 -26
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/statement_cache.rb +45 -35
- data/lib/active_record/store.rb +42 -36
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +82 -0
- data/lib/active_record/tasks/database_tasks.rb +136 -95
- data/lib/active_record/tasks/mysql_database_tasks.rb +59 -89
- data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -31
- data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -16
- data/lib/active_record/timestamp.rb +70 -38
- data/lib/active_record/touch_later.rb +64 -0
- data/lib/active_record/transactions.rb +208 -123
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type/adapter_specific_registry.rb +136 -0
- data/lib/active_record/type/date.rb +4 -41
- data/lib/active_record/type/date_time.rb +4 -38
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +30 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +11 -16
- data/lib/active_record/type/type_map.rb +15 -17
- data/lib/active_record/type/unsigned_integer.rb +9 -7
- data/lib/active_record/type.rb +79 -23
- data/lib/active_record/type_caster/connection.rb +33 -0
- data/lib/active_record/type_caster/map.rb +23 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +13 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +41 -32
- data/lib/active_record/validations.rb +38 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +36 -21
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +8 -6
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +8 -7
- data/lib/rails/generators/active_record/migration.rb +18 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +3 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +77 -53
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute.rb +0 -149
- data/lib/active_record/attribute_set/builder.rb +0 -86
- data/lib/active_record/attribute_set.rb +0 -77
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- 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/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- 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 -30
- data/lib/active_record/type/decimal.rb +0 -40
- 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 -55
- 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 -36
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -101
- /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Associations
|
3
5
|
# Association proxies in Active Record are middlemen between the object that
|
@@ -28,12 +30,12 @@ module ActiveRecord
|
|
28
30
|
# is computed directly through SQL and does not trigger by itself the
|
29
31
|
# instantiation of the actual post records.
|
30
32
|
class CollectionProxy < Relation
|
31
|
-
delegate(*(ActiveRecord::Calculations.public_instance_methods - [:count]), to: :scope)
|
32
|
-
|
33
33
|
def initialize(klass, association) #:nodoc:
|
34
34
|
@association = association
|
35
|
-
super klass
|
36
|
-
|
35
|
+
super klass
|
36
|
+
|
37
|
+
extensions = association.extensions
|
38
|
+
extend(*extensions) if extensions.any?
|
37
39
|
end
|
38
40
|
|
39
41
|
def target
|
@@ -53,6 +55,12 @@ module ActiveRecord
|
|
53
55
|
@association.loaded?
|
54
56
|
end
|
55
57
|
|
58
|
+
##
|
59
|
+
# :method: select
|
60
|
+
#
|
61
|
+
# :call-seq:
|
62
|
+
# select(*fields, &block)
|
63
|
+
#
|
56
64
|
# Works in two ways.
|
57
65
|
#
|
58
66
|
# *First:* Specify a subset of fields to be selected from the result set.
|
@@ -75,7 +83,7 @@ module ActiveRecord
|
|
75
83
|
# # #<Pet id: nil, name: "Choo-Choo">
|
76
84
|
# # ]
|
77
85
|
#
|
78
|
-
# person.pets.select(:id, :name
|
86
|
+
# person.pets.select(:id, :name)
|
79
87
|
# # => [
|
80
88
|
# # #<Pet id: 1, name: "Fancy-Fancy">,
|
81
89
|
# # #<Pet id: 2, name: "Spook">,
|
@@ -100,18 +108,9 @@ module ActiveRecord
|
|
100
108
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
101
109
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
102
110
|
# # ]
|
103
|
-
#
|
104
|
-
# person.pets.select(:name) { |pet| pet.name =~ /oo/ }
|
105
|
-
# # => [
|
106
|
-
# # #<Pet id: 2, name: "Spook">,
|
107
|
-
# # #<Pet id: 3, name: "Choo-Choo">
|
108
|
-
# # ]
|
109
|
-
def select(*fields, &block)
|
110
|
-
@association.select(*fields, &block)
|
111
|
-
end
|
112
111
|
|
113
112
|
# Finds an object in the collection responding to the +id+. Uses the same
|
114
|
-
# rules as
|
113
|
+
# rules as ActiveRecord::Base.find. Returns ActiveRecord::RecordNotFound
|
115
114
|
# error if the object cannot be found.
|
116
115
|
#
|
117
116
|
# class Person < ActiveRecord::Base
|
@@ -126,7 +125,7 @@ module ActiveRecord
|
|
126
125
|
# # ]
|
127
126
|
#
|
128
127
|
# person.pets.find(1) # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
|
129
|
-
# person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=4
|
128
|
+
# person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=4
|
130
129
|
#
|
131
130
|
# person.pets.find(2) { |pet| pet.name.downcase! }
|
132
131
|
# # => #<Pet id: 2, name: "fancy-fancy", person_id: 1>
|
@@ -136,10 +135,17 @@ module ActiveRecord
|
|
136
135
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
137
136
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
138
137
|
# # ]
|
139
|
-
def find(*args
|
140
|
-
|
138
|
+
def find(*args)
|
139
|
+
return super if block_given?
|
140
|
+
@association.find(*args)
|
141
141
|
end
|
142
142
|
|
143
|
+
##
|
144
|
+
# :method: first
|
145
|
+
#
|
146
|
+
# :call-seq:
|
147
|
+
# first(limit = nil)
|
148
|
+
#
|
143
149
|
# Returns the first record, or the first +n+ records, from the collection.
|
144
150
|
# If the collection is empty, the first form returns +nil+, and the second
|
145
151
|
# form returns an empty array.
|
@@ -166,35 +172,63 @@ module ActiveRecord
|
|
166
172
|
# another_person_without.pets # => []
|
167
173
|
# another_person_without.pets.first # => nil
|
168
174
|
# another_person_without.pets.first(3) # => []
|
169
|
-
def first(*args)
|
170
|
-
@association.first(*args)
|
171
|
-
end
|
172
175
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
176
|
+
##
|
177
|
+
# :method: second
|
178
|
+
#
|
179
|
+
# :call-seq:
|
180
|
+
# second()
|
181
|
+
#
|
182
|
+
# Same as #first except returns only the second record.
|
177
183
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
184
|
+
##
|
185
|
+
# :method: third
|
186
|
+
#
|
187
|
+
# :call-seq:
|
188
|
+
# third()
|
189
|
+
#
|
190
|
+
# Same as #first except returns only the third record.
|
182
191
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
192
|
+
##
|
193
|
+
# :method: fourth
|
194
|
+
#
|
195
|
+
# :call-seq:
|
196
|
+
# fourth()
|
197
|
+
#
|
198
|
+
# Same as #first except returns only the fourth record.
|
187
199
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
200
|
+
##
|
201
|
+
# :method: fifth
|
202
|
+
#
|
203
|
+
# :call-seq:
|
204
|
+
# fifth()
|
205
|
+
#
|
206
|
+
# Same as #first except returns only the fifth record.
|
192
207
|
|
193
|
-
|
208
|
+
##
|
209
|
+
# :method: forty_two
|
210
|
+
#
|
211
|
+
# :call-seq:
|
212
|
+
# forty_two()
|
213
|
+
#
|
214
|
+
# Same as #first except returns only the forty second record.
|
194
215
|
# Also known as accessing "the reddit".
|
195
|
-
|
196
|
-
|
197
|
-
|
216
|
+
|
217
|
+
##
|
218
|
+
# :method: third_to_last
|
219
|
+
#
|
220
|
+
# :call-seq:
|
221
|
+
# third_to_last()
|
222
|
+
#
|
223
|
+
# Same as #first except returns only the third-to-last record.
|
224
|
+
|
225
|
+
##
|
226
|
+
# :method: second_to_last
|
227
|
+
#
|
228
|
+
# :call-seq:
|
229
|
+
# second_to_last()
|
230
|
+
#
|
231
|
+
# Same as #first except returns only the second-to-last record.
|
198
232
|
|
199
233
|
# Returns the last record, or the last +n+ records, from the collection.
|
200
234
|
# If the collection is empty, the first form returns +nil+, and the second
|
@@ -222,8 +256,39 @@ module ActiveRecord
|
|
222
256
|
# another_person_without.pets # => []
|
223
257
|
# another_person_without.pets.last # => nil
|
224
258
|
# another_person_without.pets.last(3) # => []
|
225
|
-
def last(
|
226
|
-
|
259
|
+
def last(limit = nil)
|
260
|
+
load_target if find_from_target?
|
261
|
+
super
|
262
|
+
end
|
263
|
+
|
264
|
+
# Gives a record (or N records if a parameter is supplied) from the collection
|
265
|
+
# using the same rules as <tt>ActiveRecord::Base.take</tt>.
|
266
|
+
#
|
267
|
+
# class Person < ActiveRecord::Base
|
268
|
+
# has_many :pets
|
269
|
+
# end
|
270
|
+
#
|
271
|
+
# person.pets
|
272
|
+
# # => [
|
273
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
274
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
275
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
276
|
+
# # ]
|
277
|
+
#
|
278
|
+
# person.pets.take # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
|
279
|
+
#
|
280
|
+
# person.pets.take(2)
|
281
|
+
# # => [
|
282
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
283
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>
|
284
|
+
# # ]
|
285
|
+
#
|
286
|
+
# another_person_without.pets # => []
|
287
|
+
# another_person_without.pets.take # => nil
|
288
|
+
# another_person_without.pets.take(2) # => []
|
289
|
+
def take(limit = nil)
|
290
|
+
load_target if find_from_target?
|
291
|
+
super
|
227
292
|
end
|
228
293
|
|
229
294
|
# Returns a new object of the collection type that has been instantiated
|
@@ -285,7 +350,7 @@ module ActiveRecord
|
|
285
350
|
@association.create(attributes, &block)
|
286
351
|
end
|
287
352
|
|
288
|
-
# Like
|
353
|
+
# Like #create, except that if the record is invalid, raises an exception.
|
289
354
|
#
|
290
355
|
# class Person
|
291
356
|
# has_many :pets
|
@@ -301,34 +366,6 @@ module ActiveRecord
|
|
301
366
|
@association.create!(attributes, &block)
|
302
367
|
end
|
303
368
|
|
304
|
-
# Add one or more records to the collection by setting their foreign keys
|
305
|
-
# to the association's primary key. Since << flattens its argument list and
|
306
|
-
# inserts each record, +push+ and +concat+ behave identically. Returns +self+
|
307
|
-
# so method calls may be chained.
|
308
|
-
#
|
309
|
-
# class Person < ActiveRecord::Base
|
310
|
-
# has_many :pets
|
311
|
-
# end
|
312
|
-
#
|
313
|
-
# person.pets.size # => 0
|
314
|
-
# person.pets.concat(Pet.new(name: 'Fancy-Fancy'))
|
315
|
-
# person.pets.concat(Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo'))
|
316
|
-
# person.pets.size # => 3
|
317
|
-
#
|
318
|
-
# person.id # => 1
|
319
|
-
# person.pets
|
320
|
-
# # => [
|
321
|
-
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
322
|
-
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
323
|
-
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
324
|
-
# # ]
|
325
|
-
#
|
326
|
-
# person.pets.concat([Pet.new(name: 'Brain'), Pet.new(name: 'Benny')])
|
327
|
-
# person.pets.size # => 5
|
328
|
-
def concat(*records)
|
329
|
-
@association.concat(*records)
|
330
|
-
end
|
331
|
-
|
332
369
|
# Replaces this collection with +other_array+. This will perform a diff
|
333
370
|
# and delete/add only records that have changed.
|
334
371
|
#
|
@@ -359,7 +396,7 @@ module ActiveRecord
|
|
359
396
|
# specified by the +:dependent+ option. If no +:dependent+ option is given,
|
360
397
|
# then it will follow the default strategy.
|
361
398
|
#
|
362
|
-
# For
|
399
|
+
# For <tt>has_many :through</tt> associations, the default deletion strategy is
|
363
400
|
# +:delete_all+.
|
364
401
|
#
|
365
402
|
# For +has_many+ associations, the default deletion strategy is +:nullify+.
|
@@ -394,7 +431,7 @@ module ActiveRecord
|
|
394
431
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: nil>
|
395
432
|
# # ]
|
396
433
|
#
|
397
|
-
# Both +has_many+ and
|
434
|
+
# Both +has_many+ and <tt>has_many :through</tt> dependencies default to the
|
398
435
|
# +:delete_all+ strategy if the +:dependent+ option is set to +:destroy+.
|
399
436
|
# Records are not instantiated and callbacks will not be fired.
|
400
437
|
#
|
@@ -413,7 +450,7 @@ module ActiveRecord
|
|
413
450
|
# person.pets.delete_all
|
414
451
|
#
|
415
452
|
# Pet.find(1, 2, 3)
|
416
|
-
# # => ActiveRecord::RecordNotFound
|
453
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
|
417
454
|
#
|
418
455
|
# If it is set to <tt>:delete_all</tt>, all the objects are deleted
|
419
456
|
# *without* calling their +destroy+ method.
|
@@ -433,9 +470,9 @@ module ActiveRecord
|
|
433
470
|
# person.pets.delete_all
|
434
471
|
#
|
435
472
|
# Pet.find(1, 2, 3)
|
436
|
-
# # => ActiveRecord::RecordNotFound
|
473
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
|
437
474
|
def delete_all(dependent = nil)
|
438
|
-
@association.delete_all(dependent)
|
475
|
+
@association.delete_all(dependent).tap { reset_scope }
|
439
476
|
end
|
440
477
|
|
441
478
|
# Deletes the records of the collection directly from the database
|
@@ -462,18 +499,19 @@ module ActiveRecord
|
|
462
499
|
#
|
463
500
|
# Pet.find(1) # => Couldn't find Pet with id=1
|
464
501
|
def destroy_all
|
465
|
-
@association.destroy_all
|
502
|
+
@association.destroy_all.tap { reset_scope }
|
466
503
|
end
|
467
504
|
|
468
|
-
# Deletes the +records+ supplied
|
469
|
-
#
|
470
|
-
#
|
505
|
+
# Deletes the +records+ supplied from the collection according to the strategy
|
506
|
+
# specified by the +:dependent+ option. If no +:dependent+ option is given,
|
507
|
+
# then it will follow the default strategy. Returns an array with the
|
471
508
|
# deleted records.
|
472
509
|
#
|
473
|
-
#
|
474
|
-
#
|
475
|
-
#
|
476
|
-
# strategy is
|
510
|
+
# For <tt>has_many :through</tt> associations, the default deletion strategy is
|
511
|
+
# +:delete_all+.
|
512
|
+
#
|
513
|
+
# For +has_many+ associations, the default deletion strategy is +:nullify+.
|
514
|
+
# This sets the foreign keys to +NULL+.
|
477
515
|
#
|
478
516
|
# class Person < ActiveRecord::Base
|
479
517
|
# has_many :pets # dependent: :nullify option by default
|
@@ -526,7 +564,7 @@ module ActiveRecord
|
|
526
564
|
# # => [#<Pet id: 2, name: "Spook", person_id: 1>]
|
527
565
|
#
|
528
566
|
# Pet.find(1, 3)
|
529
|
-
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with
|
567
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 3)
|
530
568
|
#
|
531
569
|
# If it is set to <tt>:delete_all</tt>, all the +records+ are deleted
|
532
570
|
# *without* calling their +destroy+ method.
|
@@ -554,9 +592,9 @@ module ActiveRecord
|
|
554
592
|
# # ]
|
555
593
|
#
|
556
594
|
# Pet.find(1)
|
557
|
-
# # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=1
|
595
|
+
# # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=1
|
558
596
|
#
|
559
|
-
# You can pass +
|
597
|
+
# You can pass +Integer+ or +String+ values, it finds the records
|
560
598
|
# responding to the +id+ and executes delete on them.
|
561
599
|
#
|
562
600
|
# class Person < ActiveRecord::Base
|
@@ -580,7 +618,7 @@ module ActiveRecord
|
|
580
618
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
581
619
|
# # ]
|
582
620
|
def delete(*records)
|
583
|
-
@association.delete(*records)
|
621
|
+
@association.delete(*records).tap { reset_scope }
|
584
622
|
end
|
585
623
|
|
586
624
|
# Destroys the +records+ supplied and removes them from the collection.
|
@@ -618,9 +656,9 @@ module ActiveRecord
|
|
618
656
|
# person.pets.size # => 0
|
619
657
|
# person.pets # => []
|
620
658
|
#
|
621
|
-
# Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with
|
659
|
+
# Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
|
622
660
|
#
|
623
|
-
# You can pass +
|
661
|
+
# You can pass +Integer+ or +String+ values, it finds the records
|
624
662
|
# responding to the +id+ and then deletes them from the database.
|
625
663
|
#
|
626
664
|
# person.pets.size # => 3
|
@@ -650,11 +688,17 @@ module ActiveRecord
|
|
650
688
|
# person.pets.size # => 0
|
651
689
|
# person.pets # => []
|
652
690
|
#
|
653
|
-
# Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with
|
691
|
+
# Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (4, 5, 6)
|
654
692
|
def destroy(*records)
|
655
|
-
@association.destroy(*records)
|
693
|
+
@association.destroy(*records).tap { reset_scope }
|
656
694
|
end
|
657
695
|
|
696
|
+
##
|
697
|
+
# :method: distinct
|
698
|
+
#
|
699
|
+
# :call-seq:
|
700
|
+
# distinct(value = true)
|
701
|
+
#
|
658
702
|
# Specifies whether the records should be unique or not.
|
659
703
|
#
|
660
704
|
# class Person < ActiveRecord::Base
|
@@ -669,17 +713,35 @@ module ActiveRecord
|
|
669
713
|
#
|
670
714
|
# person.pets.select(:name).distinct
|
671
715
|
# # => [#<Pet name: "Fancy-Fancy">]
|
672
|
-
|
673
|
-
|
716
|
+
#
|
717
|
+
# person.pets.select(:name).distinct.distinct(false)
|
718
|
+
# # => [
|
719
|
+
# # #<Pet name: "Fancy-Fancy">,
|
720
|
+
# # #<Pet name: "Fancy-Fancy">
|
721
|
+
# # ]
|
722
|
+
|
723
|
+
#--
|
724
|
+
def calculate(operation, column_name)
|
725
|
+
null_scope? ? scope.calculate(operation, column_name) : super
|
674
726
|
end
|
675
|
-
alias uniq distinct
|
676
727
|
|
677
|
-
|
728
|
+
def pluck(*column_names)
|
729
|
+
null_scope? ? scope.pluck(*column_names) : super
|
730
|
+
end
|
731
|
+
|
732
|
+
##
|
733
|
+
# :method: count
|
734
|
+
#
|
735
|
+
# :call-seq:
|
736
|
+
# count(column_name = nil, &block)
|
737
|
+
#
|
738
|
+
# Count all records.
|
678
739
|
#
|
679
740
|
# class Person < ActiveRecord::Base
|
680
741
|
# has_many :pets
|
681
742
|
# end
|
682
743
|
#
|
744
|
+
# # This will perform the count using SQL.
|
683
745
|
# person.pets.count # => 3
|
684
746
|
# person.pets
|
685
747
|
# # => [
|
@@ -687,11 +749,11 @@ module ActiveRecord
|
|
687
749
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
688
750
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
689
751
|
# # ]
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
752
|
+
#
|
753
|
+
# Passing a block will select all of a person's pets in SQL and then
|
754
|
+
# perform the count using Ruby.
|
755
|
+
#
|
756
|
+
# person.pets.count { |pet| pet.name.include?('-') } # => 2
|
695
757
|
|
696
758
|
# Returns the size of the collection. If the collection hasn't been loaded,
|
697
759
|
# it executes a <tt>SELECT COUNT(*)</tt> query. Else it calls <tt>collection.size</tt>.
|
@@ -721,6 +783,12 @@ module ActiveRecord
|
|
721
783
|
@association.size
|
722
784
|
end
|
723
785
|
|
786
|
+
##
|
787
|
+
# :method: length
|
788
|
+
#
|
789
|
+
# :call-seq:
|
790
|
+
# length()
|
791
|
+
#
|
724
792
|
# Returns the size of the collection calling +size+ on the target.
|
725
793
|
# If the collection has been already loaded, +length+ and +size+ are
|
726
794
|
# equivalent. If not and you are going to need the records anyway this
|
@@ -741,14 +809,11 @@ module ActiveRecord
|
|
741
809
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
742
810
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
743
811
|
# # ]
|
744
|
-
def length
|
745
|
-
@association.length
|
746
|
-
end
|
747
812
|
|
748
813
|
# Returns +true+ if the collection is empty. If the collection has been
|
749
814
|
# loaded it is equivalent
|
750
815
|
# to <tt>collection.size.zero?</tt>. If the collection has not been loaded,
|
751
|
-
# it is equivalent to <tt
|
816
|
+
# it is equivalent to <tt>!collection.exists?</tt>. If the collection has
|
752
817
|
# not already been loaded and you are going to fetch the records anyway it
|
753
818
|
# is better to check <tt>collection.length.zero?</tt>.
|
754
819
|
#
|
@@ -767,6 +832,12 @@ module ActiveRecord
|
|
767
832
|
@association.empty?
|
768
833
|
end
|
769
834
|
|
835
|
+
##
|
836
|
+
# :method: any?
|
837
|
+
#
|
838
|
+
# :call-seq:
|
839
|
+
# any?()
|
840
|
+
#
|
770
841
|
# Returns +true+ if the collection is not empty.
|
771
842
|
#
|
772
843
|
# class Person < ActiveRecord::Base
|
@@ -777,7 +848,7 @@ module ActiveRecord
|
|
777
848
|
# person.pets.any? # => false
|
778
849
|
#
|
779
850
|
# person.pets << Pet.new(name: 'Snoop')
|
780
|
-
# person.pets.count # =>
|
851
|
+
# person.pets.count # => 1
|
781
852
|
# person.pets.any? # => true
|
782
853
|
#
|
783
854
|
# You can also pass a +block+ to define criteria. The behavior
|
@@ -796,10 +867,13 @@ module ActiveRecord
|
|
796
867
|
# pet.group == 'dogs'
|
797
868
|
# end
|
798
869
|
# # => true
|
799
|
-
def any?(&block)
|
800
|
-
@association.any?(&block)
|
801
|
-
end
|
802
870
|
|
871
|
+
##
|
872
|
+
# :method: many?
|
873
|
+
#
|
874
|
+
# :call-seq:
|
875
|
+
# many?()
|
876
|
+
#
|
803
877
|
# Returns true if the collection has more than one record.
|
804
878
|
# Equivalent to <tt>collection.size > 1</tt>.
|
805
879
|
#
|
@@ -834,9 +908,6 @@ module ActiveRecord
|
|
834
908
|
# pet.group == 'cats'
|
835
909
|
# end
|
836
910
|
# # => true
|
837
|
-
def many?(&block)
|
838
|
-
@association.many?(&block)
|
839
|
-
end
|
840
911
|
|
841
912
|
# Returns +true+ if the given +record+ is present in the collection.
|
842
913
|
#
|
@@ -852,27 +923,14 @@ module ActiveRecord
|
|
852
923
|
!!@association.include?(record)
|
853
924
|
end
|
854
925
|
|
855
|
-
def arel
|
856
|
-
scope.arel
|
857
|
-
end
|
858
|
-
|
859
926
|
def proxy_association
|
860
927
|
@association
|
861
928
|
end
|
862
929
|
|
863
|
-
# We don't want this object to be put on the scoping stack, because
|
864
|
-
# that could create an infinite loop where we call an @association
|
865
|
-
# method, which gets the current scope, which is this object, which
|
866
|
-
# delegates to @association, and so on.
|
867
|
-
def scoping
|
868
|
-
@association.scope.scoping { yield }
|
869
|
-
end
|
870
|
-
|
871
930
|
# Returns a <tt>Relation</tt> object for the records in this association
|
872
931
|
def scope
|
873
|
-
@association.scope
|
932
|
+
@scope ||= @association.scope
|
874
933
|
end
|
875
|
-
alias spawn scope
|
876
934
|
|
877
935
|
# Equivalent to <tt>Array#==</tt>. Returns +true+ if the two arrays
|
878
936
|
# contain the same number of elements and if each element is equal
|
@@ -902,6 +960,12 @@ module ActiveRecord
|
|
902
960
|
load_target == other
|
903
961
|
end
|
904
962
|
|
963
|
+
##
|
964
|
+
# :method: to_ary
|
965
|
+
#
|
966
|
+
# :call-seq:
|
967
|
+
# to_ary()
|
968
|
+
#
|
905
969
|
# Returns a new array of objects from the collection. If the collection
|
906
970
|
# hasn't been loaded, it fetches the records from the database.
|
907
971
|
#
|
@@ -935,14 +999,15 @@ module ActiveRecord
|
|
935
999
|
# # #<Pet id: 5, name: "Brain", person_id: 1>,
|
936
1000
|
# # #<Pet id: 6, name: "Boss", person_id: 1>
|
937
1001
|
# # ]
|
938
|
-
|
939
|
-
|
1002
|
+
|
1003
|
+
def records # :nodoc:
|
1004
|
+
load_target
|
940
1005
|
end
|
941
|
-
alias_method :to_a, :to_ary
|
942
1006
|
|
943
1007
|
# Adds one or more +records+ to the collection by setting their foreign keys
|
944
|
-
# to the association's primary key.
|
945
|
-
#
|
1008
|
+
# to the association's primary key. Since +<<+ flattens its argument list and
|
1009
|
+
# inserts each record, +push+ and +concat+ behave identically. Returns +self+
|
1010
|
+
# so several appends may be chained together.
|
946
1011
|
#
|
947
1012
|
# class Person < ActiveRecord::Base
|
948
1013
|
# has_many :pets
|
@@ -965,21 +1030,24 @@ module ActiveRecord
|
|
965
1030
|
end
|
966
1031
|
alias_method :push, :<<
|
967
1032
|
alias_method :append, :<<
|
1033
|
+
alias_method :concat, :<<
|
968
1034
|
|
969
1035
|
def prepend(*args)
|
970
|
-
raise NoMethodError, "prepend on association is not defined. Please use
|
1036
|
+
raise NoMethodError, "prepend on association is not defined. Please use <<, push or append"
|
971
1037
|
end
|
972
1038
|
|
973
1039
|
# Equivalent to +delete_all+. The difference is that returns +self+, instead
|
974
1040
|
# of an array with the deleted objects, so methods can be chained. See
|
975
1041
|
# +delete_all+ for more information.
|
1042
|
+
# Note that because +delete_all+ removes records by directly
|
1043
|
+
# running an SQL query into the database, the +updated_at+ column of
|
1044
|
+
# the object is not changed.
|
976
1045
|
def clear
|
977
1046
|
delete_all
|
978
1047
|
self
|
979
1048
|
end
|
980
1049
|
|
981
1050
|
# Reloads the collection from the database. Returns +self+.
|
982
|
-
# Equivalent to <tt>collection(true)</tt>.
|
983
1051
|
#
|
984
1052
|
# class Person < ActiveRecord::Base
|
985
1053
|
# has_many :pets
|
@@ -993,12 +1061,9 @@ module ActiveRecord
|
|
993
1061
|
#
|
994
1062
|
# person.pets.reload # fetches pets from the database
|
995
1063
|
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
996
|
-
#
|
997
|
-
# person.pets(true) # fetches pets from the database
|
998
|
-
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
999
1064
|
def reload
|
1000
1065
|
proxy_association.reload
|
1001
|
-
|
1066
|
+
reset_scope
|
1002
1067
|
end
|
1003
1068
|
|
1004
1069
|
# Unloads the association. Returns +self+.
|
@@ -1020,8 +1085,47 @@ module ActiveRecord
|
|
1020
1085
|
def reset
|
1021
1086
|
proxy_association.reset
|
1022
1087
|
proxy_association.reset_scope
|
1088
|
+
reset_scope
|
1089
|
+
end
|
1090
|
+
|
1091
|
+
def reset_scope # :nodoc:
|
1092
|
+
@offsets = {}
|
1093
|
+
@scope = nil
|
1023
1094
|
self
|
1024
1095
|
end
|
1096
|
+
|
1097
|
+
delegate_methods = [
|
1098
|
+
QueryMethods,
|
1099
|
+
SpawnMethods,
|
1100
|
+
].flat_map { |klass|
|
1101
|
+
klass.public_instance_methods(false)
|
1102
|
+
} - self.public_instance_methods(false) - [:select] + [:scoping]
|
1103
|
+
|
1104
|
+
delegate(*delegate_methods, to: :scope)
|
1105
|
+
|
1106
|
+
private
|
1107
|
+
|
1108
|
+
def find_nth_with_limit(index, limit)
|
1109
|
+
load_target if find_from_target?
|
1110
|
+
super
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
def find_nth_from_last(index)
|
1114
|
+
load_target if find_from_target?
|
1115
|
+
super
|
1116
|
+
end
|
1117
|
+
|
1118
|
+
def null_scope?
|
1119
|
+
@association.null_scope?
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
def find_from_target?
|
1123
|
+
@association.find_from_target?
|
1124
|
+
end
|
1125
|
+
|
1126
|
+
def exec_queries
|
1127
|
+
load_target
|
1128
|
+
end
|
1025
1129
|
end
|
1026
1130
|
end
|
1027
1131
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord::Associations
|
4
|
+
module ForeignAssociation # :nodoc:
|
5
|
+
def foreign_key_present?
|
6
|
+
if reflection.klass.primary_key
|
7
|
+
owner.attribute_present?(reflection.active_record_primary_key)
|
8
|
+
else
|
9
|
+
false
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|