activerecord 5.0.7.2 → 5.1.0.beta1
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 +389 -2252
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/examples/performance.rb +28 -28
- data/examples/simple.rb +3 -3
- data/lib/active_record.rb +20 -20
- data/lib/active_record/aggregations.rb +244 -244
- data/lib/active_record/association_relation.rb +5 -5
- data/lib/active_record/associations.rb +1579 -1569
- data/lib/active_record/associations/alias_tracker.rb +1 -1
- data/lib/active_record/associations/association.rb +23 -15
- data/lib/active_record/associations/association_scope.rb +83 -81
- data/lib/active_record/associations/belongs_to_association.rb +0 -1
- data/lib/active_record/associations/builder/belongs_to.rb +16 -14
- data/lib/active_record/associations/builder/collection_association.rb +1 -2
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
- data/lib/active_record/associations/collection_association.rb +74 -241
- data/lib/active_record/associations/collection_proxy.rb +144 -70
- data/lib/active_record/associations/has_many_association.rb +15 -19
- data/lib/active_record/associations/has_many_through_association.rb +12 -5
- data/lib/active_record/associations/has_one_association.rb +22 -28
- data/lib/active_record/associations/has_one_through_association.rb +5 -1
- data/lib/active_record/associations/join_dependency.rb +117 -115
- data/lib/active_record/associations/join_dependency/join_association.rb +16 -13
- data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
- data/lib/active_record/associations/preloader.rb +94 -94
- data/lib/active_record/associations/preloader/association.rb +87 -64
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
- data/lib/active_record/associations/preloader/collection_association.rb +6 -6
- data/lib/active_record/associations/preloader/has_many.rb +0 -2
- data/lib/active_record/associations/preloader/singular_association.rb +6 -8
- data/lib/active_record/associations/preloader/through_association.rb +34 -41
- data/lib/active_record/associations/singular_association.rb +8 -25
- data/lib/active_record/associations/through_association.rb +3 -6
- data/lib/active_record/attribute.rb +98 -71
- data/lib/active_record/attribute/user_provided_default.rb +4 -2
- data/lib/active_record/attribute_assignment.rb +61 -61
- data/lib/active_record/attribute_decorators.rb +35 -13
- data/lib/active_record/attribute_methods.rb +56 -65
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
- data/lib/active_record/attribute_methods/dirty.rb +216 -34
- data/lib/active_record/attribute_methods/primary_key.rb +78 -73
- data/lib/active_record/attribute_methods/read.rb +39 -35
- data/lib/active_record/attribute_methods/serialization.rb +7 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
- data/lib/active_record/attribute_methods/write.rb +36 -30
- data/lib/active_record/attribute_mutation_tracker.rb +53 -10
- data/lib/active_record/attribute_set.rb +9 -6
- data/lib/active_record/attribute_set/builder.rb +41 -49
- data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
- data/lib/active_record/attributes.rb +21 -21
- data/lib/active_record/autosave_association.rb +13 -13
- data/lib/active_record/base.rb +24 -22
- data/lib/active_record/callbacks.rb +52 -14
- data/lib/active_record/coders/yaml_column.rb +9 -11
- data/lib/active_record/collection_cache_key.rb +6 -17
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +320 -278
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +22 -34
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +44 -57
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +9 -19
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +78 -79
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +99 -93
- data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -5
- data/lib/active_record/connection_adapters/abstract_adapter.rb +156 -128
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +424 -382
- data/lib/active_record/connection_adapters/column.rb +27 -5
- data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
- data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -43
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
- data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +49 -31
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +5 -6
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +24 -26
- data/lib/active_record/connection_adapters/postgresql/column.rb +1 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -35
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +9 -9
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
- data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +28 -30
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +38 -36
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +161 -170
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +179 -152
- data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -20
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +187 -130
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
- data/lib/active_record/connection_handling.rb +14 -26
- data/lib/active_record/core.rb +110 -93
- data/lib/active_record/counter_cache.rb +62 -13
- data/lib/active_record/define_callbacks.rb +20 -0
- data/lib/active_record/dynamic_matchers.rb +80 -79
- data/lib/active_record/enum.rb +8 -6
- data/lib/active_record/errors.rb +58 -15
- data/lib/active_record/explain.rb +1 -2
- data/lib/active_record/explain_registry.rb +1 -1
- data/lib/active_record/explain_subscriber.rb +7 -4
- data/lib/active_record/fixture_set/file.rb +11 -8
- data/lib/active_record/fixtures.rb +66 -53
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +93 -79
- data/lib/active_record/integration.rb +7 -7
- data/lib/active_record/internal_metadata.rb +3 -16
- data/lib/active_record/legacy_yaml_adapter.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +64 -56
- data/lib/active_record/locking/pessimistic.rb +10 -1
- data/lib/active_record/log_subscriber.rb +29 -29
- data/lib/active_record/migration.rb +155 -172
- data/lib/active_record/migration/command_recorder.rb +94 -94
- data/lib/active_record/migration/compatibility.rb +76 -37
- data/lib/active_record/migration/join_table.rb +6 -6
- data/lib/active_record/model_schema.rb +85 -119
- data/lib/active_record/nested_attributes.rb +200 -199
- data/lib/active_record/null_relation.rb +10 -33
- data/lib/active_record/persistence.rb +45 -38
- data/lib/active_record/query_cache.rb +4 -8
- data/lib/active_record/querying.rb +2 -3
- data/lib/active_record/railtie.rb +16 -17
- data/lib/active_record/railties/controller_runtime.rb +6 -2
- data/lib/active_record/railties/databases.rake +125 -140
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +2 -2
- data/lib/active_record/reflection.rb +79 -96
- data/lib/active_record/relation.rb +72 -115
- data/lib/active_record/relation/batches.rb +87 -58
- data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
- data/lib/active_record/relation/calculations.rb +154 -160
- data/lib/active_record/relation/delegation.rb +30 -29
- data/lib/active_record/relation/finder_methods.rb +195 -226
- data/lib/active_record/relation/merger.rb +58 -62
- data/lib/active_record/relation/predicate_builder.rb +92 -89
- data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
- data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
- data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
- data/lib/active_record/relation/query_attribute.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +247 -295
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +4 -5
- data/lib/active_record/relation/where_clause.rb +79 -65
- data/lib/active_record/relation/where_clause_factory.rb +47 -8
- data/lib/active_record/result.rb +29 -31
- data/lib/active_record/runtime_registry.rb +3 -3
- data/lib/active_record/sanitization.rb +182 -197
- data/lib/active_record/schema.rb +3 -3
- data/lib/active_record/schema_dumper.rb +14 -37
- data/lib/active_record/schema_migration.rb +3 -3
- data/lib/active_record/scoping.rb +9 -10
- data/lib/active_record/scoping/default.rb +87 -91
- data/lib/active_record/scoping/named.rb +16 -28
- data/lib/active_record/secure_token.rb +2 -2
- data/lib/active_record/statement_cache.rb +13 -15
- data/lib/active_record/store.rb +31 -32
- data/lib/active_record/suppressor.rb +2 -1
- data/lib/active_record/table_metadata.rb +9 -5
- data/lib/active_record/tasks/database_tasks.rb +72 -65
- data/lib/active_record/tasks/mysql_database_tasks.rb +75 -72
- data/lib/active_record/tasks/postgresql_database_tasks.rb +53 -48
- data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
- data/lib/active_record/timestamp.rb +39 -25
- data/lib/active_record/touch_later.rb +1 -2
- data/lib/active_record/transactions.rb +98 -110
- data/lib/active_record/type.rb +17 -13
- data/lib/active_record/type/adapter_specific_registry.rb +46 -42
- data/lib/active_record/type/decimal_without_scale.rb +9 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
- data/lib/active_record/type/serialized.rb +8 -8
- data/lib/active_record/type/text.rb +9 -0
- data/lib/active_record/type/time.rb +0 -1
- data/lib/active_record/type/type_map.rb +11 -15
- data/lib/active_record/type/unsigned_integer.rb +15 -0
- data/lib/active_record/type_caster.rb +2 -2
- data/lib/active_record/type_caster/connection.rb +8 -6
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/validations.rb +4 -4
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record/validations/presence.rb +2 -2
- data/lib/active_record/validations/uniqueness.rb +8 -39
- data/lib/active_record/version.rb +1 -1
- data/lib/rails/generators/active_record.rb +4 -4
- data/lib/rails/generators/active_record/migration.rb +2 -2
- data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
- metadata +22 -13
- data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -31,9 +31,6 @@ module ActiveRecord
|
|
31
31
|
def initialize(klass, association) #:nodoc:
|
32
32
|
@association = association
|
33
33
|
super klass, klass.arel_table, klass.predicate_builder
|
34
|
-
|
35
|
-
extensions = association.extensions
|
36
|
-
extend(*extensions) if extensions.any?
|
37
34
|
end
|
38
35
|
|
39
36
|
def target
|
@@ -53,6 +50,12 @@ module ActiveRecord
|
|
53
50
|
@association.loaded?
|
54
51
|
end
|
55
52
|
|
53
|
+
##
|
54
|
+
# :method: select
|
55
|
+
#
|
56
|
+
# :call-seq:
|
57
|
+
# select(*fields, &block)
|
58
|
+
#
|
56
59
|
# Works in two ways.
|
57
60
|
#
|
58
61
|
# *First:* Specify a subset of fields to be selected from the result set.
|
@@ -100,15 +103,6 @@ module ActiveRecord
|
|
100
103
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
101
104
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
102
105
|
# # ]
|
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
106
|
|
113
107
|
# Finds an object in the collection responding to the +id+. Uses the same
|
114
108
|
# rules as ActiveRecord::Base.find. Returns ActiveRecord::RecordNotFound
|
@@ -140,6 +134,12 @@ module ActiveRecord
|
|
140
134
|
@association.find(*args, &block)
|
141
135
|
end
|
142
136
|
|
137
|
+
##
|
138
|
+
# :method: first
|
139
|
+
#
|
140
|
+
# :call-seq:
|
141
|
+
# first(limit = nil)
|
142
|
+
#
|
143
143
|
# Returns the first record, or the first +n+ records, from the collection.
|
144
144
|
# If the collection is empty, the first form returns +nil+, and the second
|
145
145
|
# form returns an empty array.
|
@@ -166,45 +166,63 @@ module ActiveRecord
|
|
166
166
|
# another_person_without.pets # => []
|
167
167
|
# another_person_without.pets.first # => nil
|
168
168
|
# another_person_without.pets.first(3) # => []
|
169
|
-
def first(*args)
|
170
|
-
@association.first(*args)
|
171
|
-
end
|
172
169
|
|
170
|
+
##
|
171
|
+
# :method: second
|
172
|
+
#
|
173
|
+
# :call-seq:
|
174
|
+
# second()
|
175
|
+
#
|
173
176
|
# Same as #first except returns only the second record.
|
174
|
-
def second(*args)
|
175
|
-
@association.second(*args)
|
176
|
-
end
|
177
177
|
|
178
|
+
##
|
179
|
+
# :method: third
|
180
|
+
#
|
181
|
+
# :call-seq:
|
182
|
+
# third()
|
183
|
+
#
|
178
184
|
# Same as #first except returns only the third record.
|
179
|
-
def third(*args)
|
180
|
-
@association.third(*args)
|
181
|
-
end
|
182
185
|
|
186
|
+
##
|
187
|
+
# :method: fourth
|
188
|
+
#
|
189
|
+
# :call-seq:
|
190
|
+
# fourth()
|
191
|
+
#
|
183
192
|
# Same as #first except returns only the fourth record.
|
184
|
-
def fourth(*args)
|
185
|
-
@association.fourth(*args)
|
186
|
-
end
|
187
193
|
|
194
|
+
##
|
195
|
+
# :method: fifth
|
196
|
+
#
|
197
|
+
# :call-seq:
|
198
|
+
# fifth()
|
199
|
+
#
|
188
200
|
# Same as #first except returns only the fifth record.
|
189
|
-
def fifth(*args)
|
190
|
-
@association.fifth(*args)
|
191
|
-
end
|
192
201
|
|
202
|
+
##
|
203
|
+
# :method: forty_two
|
204
|
+
#
|
205
|
+
# :call-seq:
|
206
|
+
# forty_two()
|
207
|
+
#
|
193
208
|
# Same as #first except returns only the forty second record.
|
194
209
|
# Also known as accessing "the reddit".
|
195
|
-
def forty_two(*args)
|
196
|
-
@association.forty_two(*args)
|
197
|
-
end
|
198
210
|
|
211
|
+
##
|
212
|
+
# :method: third_to_last
|
213
|
+
#
|
214
|
+
# :call-seq:
|
215
|
+
# third_to_last()
|
216
|
+
#
|
199
217
|
# Same as #first except returns only the third-to-last record.
|
200
|
-
def third_to_last(*args)
|
201
|
-
@association.third_to_last(*args)
|
202
|
-
end
|
203
218
|
|
219
|
+
##
|
220
|
+
# :method: second_to_last
|
221
|
+
#
|
222
|
+
# :call-seq:
|
223
|
+
# second_to_last()
|
224
|
+
#
|
204
225
|
# Same as #first except returns only the second-to-last record.
|
205
|
-
def second_to_last(*args)
|
206
|
-
@association.second_to_last(*args)
|
207
|
-
end
|
208
226
|
|
209
227
|
# Returns the last record, or the last +n+ records, from the collection.
|
210
228
|
# If the collection is empty, the first form returns +nil+, and the second
|
@@ -232,8 +250,9 @@ module ActiveRecord
|
|
232
250
|
# another_person_without.pets # => []
|
233
251
|
# another_person_without.pets.last # => nil
|
234
252
|
# another_person_without.pets.last(3) # => []
|
235
|
-
def last(
|
236
|
-
|
253
|
+
def last(limit = nil)
|
254
|
+
load_target if find_from_target?
|
255
|
+
super
|
237
256
|
end
|
238
257
|
|
239
258
|
# Gives a record (or N records if a parameter is supplied) from the collection
|
@@ -261,8 +280,9 @@ module ActiveRecord
|
|
261
280
|
# another_person_without.pets # => []
|
262
281
|
# another_person_without.pets.take # => nil
|
263
282
|
# another_person_without.pets.take(2) # => []
|
264
|
-
def take(
|
265
|
-
|
283
|
+
def take(limit = nil)
|
284
|
+
load_target if find_from_target?
|
285
|
+
super
|
266
286
|
end
|
267
287
|
|
268
288
|
# Returns a new object of the collection type that has been instantiated
|
@@ -695,6 +715,12 @@ module ActiveRecord
|
|
695
715
|
@association.destroy(*records)
|
696
716
|
end
|
697
717
|
|
718
|
+
##
|
719
|
+
# :method: distinct
|
720
|
+
#
|
721
|
+
# :call-seq:
|
722
|
+
# distinct(value = true)
|
723
|
+
#
|
698
724
|
# Specifies whether the records should be unique or not.
|
699
725
|
#
|
700
726
|
# class Person < ActiveRecord::Base
|
@@ -709,17 +735,39 @@ module ActiveRecord
|
|
709
735
|
#
|
710
736
|
# person.pets.select(:name).distinct
|
711
737
|
# # => [#<Pet name: "Fancy-Fancy">]
|
712
|
-
|
713
|
-
|
738
|
+
#
|
739
|
+
# person.pets.select(:name).distinct.distinct(false)
|
740
|
+
# # => [
|
741
|
+
# # #<Pet name: "Fancy-Fancy">,
|
742
|
+
# # #<Pet name: "Fancy-Fancy">
|
743
|
+
# # ]
|
744
|
+
|
745
|
+
#--
|
746
|
+
def uniq
|
747
|
+
load_target.uniq
|
714
748
|
end
|
715
|
-
alias uniq distinct
|
716
749
|
|
717
|
-
|
750
|
+
def calculate(operation, column_name)
|
751
|
+
null_scope? ? scope.calculate(operation, column_name) : super
|
752
|
+
end
|
753
|
+
|
754
|
+
def pluck(*column_names)
|
755
|
+
null_scope? ? scope.pluck(*column_names) : super
|
756
|
+
end
|
757
|
+
|
758
|
+
##
|
759
|
+
# :method: count
|
760
|
+
#
|
761
|
+
# :call-seq:
|
762
|
+
# count(column_name = nil, &block)
|
763
|
+
#
|
764
|
+
# Count all records.
|
718
765
|
#
|
719
766
|
# class Person < ActiveRecord::Base
|
720
767
|
# has_many :pets
|
721
768
|
# end
|
722
769
|
#
|
770
|
+
# # This will perform the count using SQL.
|
723
771
|
# person.pets.count # => 3
|
724
772
|
# person.pets
|
725
773
|
# # => [
|
@@ -727,17 +775,11 @@ module ActiveRecord
|
|
727
775
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
728
776
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
729
777
|
# # ]
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
null_scope? ? scope.calculate(operation, column_name) : super
|
736
|
-
end
|
737
|
-
|
738
|
-
def pluck(*column_names)
|
739
|
-
null_scope? ? scope.pluck(*column_names) : super
|
740
|
-
end
|
778
|
+
#
|
779
|
+
# Passing a block will select all of a person's pets in SQL and then
|
780
|
+
# perform the count using Ruby.
|
781
|
+
#
|
782
|
+
# person.pets.count { |pet| pet.name.include?('-') } # => 2
|
741
783
|
|
742
784
|
# Returns the size of the collection. If the collection hasn't been loaded,
|
743
785
|
# it executes a <tt>SELECT COUNT(*)</tt> query. Else it calls <tt>collection.size</tt>.
|
@@ -767,6 +809,12 @@ module ActiveRecord
|
|
767
809
|
@association.size
|
768
810
|
end
|
769
811
|
|
812
|
+
##
|
813
|
+
# :method: length
|
814
|
+
#
|
815
|
+
# :call-seq:
|
816
|
+
# length()
|
817
|
+
#
|
770
818
|
# Returns the size of the collection calling +size+ on the target.
|
771
819
|
# If the collection has been already loaded, +length+ and +size+ are
|
772
820
|
# equivalent. If not and you are going to need the records anyway this
|
@@ -787,9 +835,6 @@ module ActiveRecord
|
|
787
835
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
788
836
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
789
837
|
# # ]
|
790
|
-
def length
|
791
|
-
@association.length
|
792
|
-
end
|
793
838
|
|
794
839
|
# Returns +true+ if the collection is empty. If the collection has been
|
795
840
|
# loaded it is equivalent
|
@@ -813,6 +858,12 @@ module ActiveRecord
|
|
813
858
|
@association.empty?
|
814
859
|
end
|
815
860
|
|
861
|
+
##
|
862
|
+
# :method: any?
|
863
|
+
#
|
864
|
+
# :call-seq:
|
865
|
+
# any?()
|
866
|
+
#
|
816
867
|
# Returns +true+ if the collection is not empty.
|
817
868
|
#
|
818
869
|
# class Person < ActiveRecord::Base
|
@@ -842,10 +893,13 @@ module ActiveRecord
|
|
842
893
|
# pet.group == 'dogs'
|
843
894
|
# end
|
844
895
|
# # => true
|
845
|
-
def any?(&block)
|
846
|
-
@association.any?(&block)
|
847
|
-
end
|
848
896
|
|
897
|
+
##
|
898
|
+
# :method: many?
|
899
|
+
#
|
900
|
+
# :call-seq:
|
901
|
+
# many?()
|
902
|
+
#
|
849
903
|
# Returns true if the collection has more than one record.
|
850
904
|
# Equivalent to <tt>collection.size > 1</tt>.
|
851
905
|
#
|
@@ -880,9 +934,6 @@ module ActiveRecord
|
|
880
934
|
# pet.group == 'cats'
|
881
935
|
# end
|
882
936
|
# # => true
|
883
|
-
def many?(&block)
|
884
|
-
@association.many?(&block)
|
885
|
-
end
|
886
937
|
|
887
938
|
# Returns +true+ if the given +record+ is present in the collection.
|
888
939
|
#
|
@@ -1037,8 +1088,9 @@ module ActiveRecord
|
|
1037
1088
|
# person.pets(true) # fetches pets from the database
|
1038
1089
|
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
1039
1090
|
def reload
|
1091
|
+
@scope = nil
|
1040
1092
|
proxy_association.reload
|
1041
|
-
|
1093
|
+
self
|
1042
1094
|
end
|
1043
1095
|
|
1044
1096
|
# Unloads the association. Returns +self+.
|
@@ -1058,13 +1110,9 @@ module ActiveRecord
|
|
1058
1110
|
# person.pets # fetches pets from the database
|
1059
1111
|
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
1060
1112
|
def reset
|
1113
|
+
@scope = nil
|
1061
1114
|
proxy_association.reset
|
1062
1115
|
proxy_association.reset_scope
|
1063
|
-
reset_scope
|
1064
|
-
end
|
1065
|
-
|
1066
|
-
def reset_scope # :nodoc:
|
1067
|
-
@scope = nil
|
1068
1116
|
self
|
1069
1117
|
end
|
1070
1118
|
|
@@ -1079,13 +1127,39 @@ module ActiveRecord
|
|
1079
1127
|
|
1080
1128
|
private
|
1081
1129
|
|
1130
|
+
def find_nth_with_limit(index, limit)
|
1131
|
+
load_target if find_from_target?
|
1132
|
+
super
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
def find_nth_from_last(index)
|
1136
|
+
load_target if find_from_target?
|
1137
|
+
super
|
1138
|
+
end
|
1139
|
+
|
1082
1140
|
def null_scope?
|
1083
1141
|
@association.null_scope?
|
1084
1142
|
end
|
1085
1143
|
|
1144
|
+
def find_from_target?
|
1145
|
+
@association.find_from_target?
|
1146
|
+
end
|
1147
|
+
|
1086
1148
|
def exec_queries
|
1087
1149
|
load_target
|
1088
1150
|
end
|
1151
|
+
|
1152
|
+
def respond_to_missing?(method, _)
|
1153
|
+
scope.respond_to?(method) || super
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
def method_missing(method, *args, &block)
|
1157
|
+
if scope.respond_to?(method)
|
1158
|
+
scope.public_send(method, *args, &block)
|
1159
|
+
else
|
1160
|
+
super
|
1161
|
+
end
|
1162
|
+
end
|
1089
1163
|
end
|
1090
1164
|
end
|
1091
1165
|
end
|
@@ -16,31 +16,27 @@ module ActiveRecord
|
|
16
16
|
when :restrict_with_error
|
17
17
|
unless empty?
|
18
18
|
record = owner.class.human_attribute_name(reflection.name).downcase
|
19
|
-
|
20
|
-
if message
|
21
|
-
ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
|
22
|
-
The error key `:'restrict_dependent_destroy.many'` has been deprecated and will be removed in Rails 5.1.
|
23
|
-
Please use `:'restrict_dependent_destroy.has_many'` instead.
|
24
|
-
MESSAGE
|
25
|
-
end
|
26
|
-
owner.errors.add(:base, message || :'restrict_dependent_destroy.has_many', record: record)
|
19
|
+
owner.errors.add(:base, :'restrict_dependent_destroy.has_many', record: record)
|
27
20
|
throw(:abort)
|
28
21
|
end
|
29
22
|
|
23
|
+
when :destroy
|
24
|
+
# No point in executing the counter update since we're going to destroy the parent anyway
|
25
|
+
load_target.each { |t| t.destroyed_by_association = reflection }
|
26
|
+
destroy_all
|
30
27
|
else
|
31
|
-
|
32
|
-
# No point in executing the counter update since we're going to destroy the parent anyway
|
33
|
-
load_target.each { |t| t.destroyed_by_association = reflection }
|
34
|
-
destroy_all
|
35
|
-
else
|
36
|
-
delete_all
|
37
|
-
end
|
28
|
+
delete_all
|
38
29
|
end
|
39
30
|
end
|
40
31
|
|
41
32
|
def insert_record(record, validate = true, raise = false)
|
42
33
|
set_owner_attributes(record)
|
43
|
-
|
34
|
+
|
35
|
+
if raise
|
36
|
+
record.save!(validate: validate)
|
37
|
+
else
|
38
|
+
record.save(validate: validate)
|
39
|
+
end
|
44
40
|
end
|
45
41
|
|
46
42
|
def empty?
|
@@ -68,7 +64,7 @@ module ActiveRecord
|
|
68
64
|
# the loaded flag is set to true as well.
|
69
65
|
def count_records
|
70
66
|
count = if reflection.has_cached_counter?
|
71
|
-
owner._read_attribute
|
67
|
+
owner._read_attribute(reflection.counter_cache_column).to_i
|
72
68
|
else
|
73
69
|
scope.count
|
74
70
|
end
|
@@ -76,7 +72,7 @@ module ActiveRecord
|
|
76
72
|
# If there's nothing in the database and @target has no new records
|
77
73
|
# we are certain the current target is an empty array. This is a
|
78
74
|
# documented side-effect of the method that may avoid an extra SELECT.
|
79
|
-
@target ||= []
|
75
|
+
(@target ||= []) && loaded! if count == 0
|
80
76
|
|
81
77
|
[association_scope.limit_value, count].compact.min
|
82
78
|
end
|
@@ -104,7 +100,7 @@ module ActiveRecord
|
|
104
100
|
end
|
105
101
|
|
106
102
|
def delete_or_nullify_all_records(method)
|
107
|
-
count = delete_count(method,
|
103
|
+
count = delete_count(method, scope)
|
108
104
|
update_counter(-count)
|
109
105
|
end
|
110
106
|
|
@@ -38,8 +38,12 @@ module ActiveRecord
|
|
38
38
|
def insert_record(record, validate = true, raise = false)
|
39
39
|
ensure_not_nested
|
40
40
|
|
41
|
-
if record.new_record? || record.
|
42
|
-
|
41
|
+
if record.new_record? || record.has_changes_to_save?
|
42
|
+
if raise
|
43
|
+
record.save!(validate: validate)
|
44
|
+
else
|
45
|
+
return unless record.save(validate: validate)
|
46
|
+
end
|
43
47
|
end
|
44
48
|
|
45
49
|
save_through_record(record)
|
@@ -84,7 +88,10 @@ module ActiveRecord
|
|
84
88
|
end
|
85
89
|
|
86
90
|
def save_through_record(record)
|
87
|
-
build_through_record(record)
|
91
|
+
association = build_through_record(record)
|
92
|
+
if association.changed?
|
93
|
+
association.save!
|
94
|
+
end
|
88
95
|
ensure
|
89
96
|
@through_records.delete(record.object_id)
|
90
97
|
end
|
@@ -144,7 +151,7 @@ module ActiveRecord
|
|
144
151
|
stmt.from scope.klass.arel_table
|
145
152
|
stmt.wheres = arel.constraints
|
146
153
|
|
147
|
-
count = scope.klass.connection.delete(stmt,
|
154
|
+
count = scope.klass.connection.delete(stmt, "SQL", scope.bound_attributes)
|
148
155
|
end
|
149
156
|
when :nullify
|
150
157
|
count = scope.update_all(source_reflection.foreign_key => nil)
|
@@ -194,7 +201,7 @@ module ActiveRecord
|
|
194
201
|
|
195
202
|
def find_target
|
196
203
|
return [] unless target_reflection_has_associated_record?
|
197
|
-
|
204
|
+
super
|
198
205
|
end
|
199
206
|
|
200
207
|
# NOTE - not sure that we can actually cope with inverses here
|