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.

Files changed (216) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +389 -2252
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +28 -28
  6. data/examples/simple.rb +3 -3
  7. data/lib/active_record.rb +20 -20
  8. data/lib/active_record/aggregations.rb +244 -244
  9. data/lib/active_record/association_relation.rb +5 -5
  10. data/lib/active_record/associations.rb +1579 -1569
  11. data/lib/active_record/associations/alias_tracker.rb +1 -1
  12. data/lib/active_record/associations/association.rb +23 -15
  13. data/lib/active_record/associations/association_scope.rb +83 -81
  14. data/lib/active_record/associations/belongs_to_association.rb +0 -1
  15. data/lib/active_record/associations/builder/belongs_to.rb +16 -14
  16. data/lib/active_record/associations/builder/collection_association.rb +1 -2
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
  18. data/lib/active_record/associations/collection_association.rb +74 -241
  19. data/lib/active_record/associations/collection_proxy.rb +144 -70
  20. data/lib/active_record/associations/has_many_association.rb +15 -19
  21. data/lib/active_record/associations/has_many_through_association.rb +12 -5
  22. data/lib/active_record/associations/has_one_association.rb +22 -28
  23. data/lib/active_record/associations/has_one_through_association.rb +5 -1
  24. data/lib/active_record/associations/join_dependency.rb +117 -115
  25. data/lib/active_record/associations/join_dependency/join_association.rb +16 -13
  26. data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
  27. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  28. data/lib/active_record/associations/preloader.rb +94 -94
  29. data/lib/active_record/associations/preloader/association.rb +87 -64
  30. data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
  31. data/lib/active_record/associations/preloader/collection_association.rb +6 -6
  32. data/lib/active_record/associations/preloader/has_many.rb +0 -2
  33. data/lib/active_record/associations/preloader/singular_association.rb +6 -8
  34. data/lib/active_record/associations/preloader/through_association.rb +34 -41
  35. data/lib/active_record/associations/singular_association.rb +8 -25
  36. data/lib/active_record/associations/through_association.rb +3 -6
  37. data/lib/active_record/attribute.rb +98 -71
  38. data/lib/active_record/attribute/user_provided_default.rb +4 -2
  39. data/lib/active_record/attribute_assignment.rb +61 -61
  40. data/lib/active_record/attribute_decorators.rb +35 -13
  41. data/lib/active_record/attribute_methods.rb +56 -65
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
  43. data/lib/active_record/attribute_methods/dirty.rb +216 -34
  44. data/lib/active_record/attribute_methods/primary_key.rb +78 -73
  45. data/lib/active_record/attribute_methods/read.rb +39 -35
  46. data/lib/active_record/attribute_methods/serialization.rb +7 -7
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
  48. data/lib/active_record/attribute_methods/write.rb +36 -30
  49. data/lib/active_record/attribute_mutation_tracker.rb +53 -10
  50. data/lib/active_record/attribute_set.rb +9 -6
  51. data/lib/active_record/attribute_set/builder.rb +41 -49
  52. data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
  53. data/lib/active_record/attributes.rb +21 -21
  54. data/lib/active_record/autosave_association.rb +13 -13
  55. data/lib/active_record/base.rb +24 -22
  56. data/lib/active_record/callbacks.rb +52 -14
  57. data/lib/active_record/coders/yaml_column.rb +9 -11
  58. data/lib/active_record/collection_cache_key.rb +6 -17
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +320 -278
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +22 -34
  62. data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -27
  63. data/lib/active_record/connection_adapters/abstract/quoting.rb +44 -57
  64. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +9 -19
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +78 -79
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +99 -93
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -5
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +156 -128
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +424 -382
  71. data/lib/active_record/connection_adapters/column.rb +27 -5
  72. data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
  73. data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -43
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +49 -31
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +5 -6
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +24 -26
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +1 -28
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -35
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +9 -9
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
  92. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
  93. data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
  94. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  95. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
  97. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +28 -30
  98. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
  100. data/lib/active_record/connection_adapters/postgresql/quoting.rb +38 -36
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +161 -170
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +4 -4
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -7
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +179 -152
  108. data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
  110. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -20
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
  113. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
  114. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
  115. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +187 -130
  116. data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
  117. data/lib/active_record/connection_handling.rb +14 -26
  118. data/lib/active_record/core.rb +110 -93
  119. data/lib/active_record/counter_cache.rb +62 -13
  120. data/lib/active_record/define_callbacks.rb +20 -0
  121. data/lib/active_record/dynamic_matchers.rb +80 -79
  122. data/lib/active_record/enum.rb +8 -6
  123. data/lib/active_record/errors.rb +58 -15
  124. data/lib/active_record/explain.rb +1 -2
  125. data/lib/active_record/explain_registry.rb +1 -1
  126. data/lib/active_record/explain_subscriber.rb +7 -4
  127. data/lib/active_record/fixture_set/file.rb +11 -8
  128. data/lib/active_record/fixtures.rb +66 -53
  129. data/lib/active_record/gem_version.rb +3 -3
  130. data/lib/active_record/inheritance.rb +93 -79
  131. data/lib/active_record/integration.rb +7 -7
  132. data/lib/active_record/internal_metadata.rb +3 -16
  133. data/lib/active_record/legacy_yaml_adapter.rb +1 -1
  134. data/lib/active_record/locking/optimistic.rb +64 -56
  135. data/lib/active_record/locking/pessimistic.rb +10 -1
  136. data/lib/active_record/log_subscriber.rb +29 -29
  137. data/lib/active_record/migration.rb +155 -172
  138. data/lib/active_record/migration/command_recorder.rb +94 -94
  139. data/lib/active_record/migration/compatibility.rb +76 -37
  140. data/lib/active_record/migration/join_table.rb +6 -6
  141. data/lib/active_record/model_schema.rb +85 -119
  142. data/lib/active_record/nested_attributes.rb +200 -199
  143. data/lib/active_record/null_relation.rb +10 -33
  144. data/lib/active_record/persistence.rb +45 -38
  145. data/lib/active_record/query_cache.rb +4 -8
  146. data/lib/active_record/querying.rb +2 -3
  147. data/lib/active_record/railtie.rb +16 -17
  148. data/lib/active_record/railties/controller_runtime.rb +6 -2
  149. data/lib/active_record/railties/databases.rake +125 -140
  150. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  151. data/lib/active_record/readonly_attributes.rb +2 -2
  152. data/lib/active_record/reflection.rb +79 -96
  153. data/lib/active_record/relation.rb +72 -115
  154. data/lib/active_record/relation/batches.rb +87 -58
  155. data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
  156. data/lib/active_record/relation/calculations.rb +154 -160
  157. data/lib/active_record/relation/delegation.rb +30 -29
  158. data/lib/active_record/relation/finder_methods.rb +195 -226
  159. data/lib/active_record/relation/merger.rb +58 -62
  160. data/lib/active_record/relation/predicate_builder.rb +92 -89
  161. data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
  162. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
  163. data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
  164. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
  165. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
  166. data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
  167. data/lib/active_record/relation/query_attribute.rb +1 -1
  168. data/lib/active_record/relation/query_methods.rb +247 -295
  169. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  170. data/lib/active_record/relation/spawn_methods.rb +4 -5
  171. data/lib/active_record/relation/where_clause.rb +79 -65
  172. data/lib/active_record/relation/where_clause_factory.rb +47 -8
  173. data/lib/active_record/result.rb +29 -31
  174. data/lib/active_record/runtime_registry.rb +3 -3
  175. data/lib/active_record/sanitization.rb +182 -197
  176. data/lib/active_record/schema.rb +3 -3
  177. data/lib/active_record/schema_dumper.rb +14 -37
  178. data/lib/active_record/schema_migration.rb +3 -3
  179. data/lib/active_record/scoping.rb +9 -10
  180. data/lib/active_record/scoping/default.rb +87 -91
  181. data/lib/active_record/scoping/named.rb +16 -28
  182. data/lib/active_record/secure_token.rb +2 -2
  183. data/lib/active_record/statement_cache.rb +13 -15
  184. data/lib/active_record/store.rb +31 -32
  185. data/lib/active_record/suppressor.rb +2 -1
  186. data/lib/active_record/table_metadata.rb +9 -5
  187. data/lib/active_record/tasks/database_tasks.rb +72 -65
  188. data/lib/active_record/tasks/mysql_database_tasks.rb +75 -72
  189. data/lib/active_record/tasks/postgresql_database_tasks.rb +53 -48
  190. data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
  191. data/lib/active_record/timestamp.rb +39 -25
  192. data/lib/active_record/touch_later.rb +1 -2
  193. data/lib/active_record/transactions.rb +98 -110
  194. data/lib/active_record/type.rb +17 -13
  195. data/lib/active_record/type/adapter_specific_registry.rb +46 -42
  196. data/lib/active_record/type/decimal_without_scale.rb +9 -0
  197. data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
  198. data/lib/active_record/type/serialized.rb +8 -8
  199. data/lib/active_record/type/text.rb +9 -0
  200. data/lib/active_record/type/time.rb +0 -1
  201. data/lib/active_record/type/type_map.rb +11 -15
  202. data/lib/active_record/type/unsigned_integer.rb +15 -0
  203. data/lib/active_record/type_caster.rb +2 -2
  204. data/lib/active_record/type_caster/connection.rb +8 -6
  205. data/lib/active_record/type_caster/map.rb +3 -1
  206. data/lib/active_record/validations.rb +4 -4
  207. data/lib/active_record/validations/associated.rb +1 -1
  208. data/lib/active_record/validations/presence.rb +2 -2
  209. data/lib/active_record/validations/uniqueness.rb +8 -39
  210. data/lib/active_record/version.rb +1 -1
  211. data/lib/rails/generators/active_record.rb +4 -4
  212. data/lib/rails/generators/active_record/migration.rb +2 -2
  213. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
  214. data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
  215. metadata +22 -13
  216. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -3,7 +3,7 @@ module ArJdbcMySQL #:nodoc:
3
3
  class Error < StandardError #:nodoc:
4
4
  attr_accessor :error_number, :sql_state
5
5
 
6
- def initialize msg
6
+ def initialize(msg)
7
7
  super
8
8
  @error_number = nil
9
9
  @sql_state = nil
@@ -11,12 +11,12 @@ module ActiveRecord
11
11
  # Attributes listed as readonly will be used to create a new record but update operations will
12
12
  # ignore these fields.
13
13
  def attr_readonly(*attributes)
14
- self._attr_readonly = Set.new(attributes.map(&:to_s)) + (self._attr_readonly || [])
14
+ self._attr_readonly = Set.new(attributes.map(&:to_s)) + (_attr_readonly || [])
15
15
  end
16
16
 
17
17
  # Returns an array of all the attributes that have been specified as readonly.
18
18
  def readonly_attributes
19
- self._attr_readonly
19
+ _attr_readonly
20
20
  end
21
21
  end
22
22
  end
@@ -1,5 +1,6 @@
1
- require 'thread'
2
- require 'active_support/core_ext/string/filters'
1
+ require "thread"
2
+ require "active_support/core_ext/string/filters"
3
+ require "active_support/deprecation"
3
4
 
4
5
  module ActiveRecord
5
6
  # = Active Record Reflection
@@ -14,18 +15,19 @@ module ActiveRecord
14
15
  end
15
16
 
16
17
  def self.create(macro, name, scope, options, ar)
17
- klass = case macro
18
- when :composed_of
19
- AggregateReflection
20
- when :has_many
21
- HasManyReflection
22
- when :has_one
23
- HasOneReflection
24
- when :belongs_to
25
- BelongsToReflection
26
- else
27
- raise "Unsupported Macro: #{macro}"
28
- end
18
+ klass = \
19
+ case macro
20
+ when :composed_of
21
+ AggregateReflection
22
+ when :has_many
23
+ HasManyReflection
24
+ when :has_one
25
+ HasOneReflection
26
+ when :belongs_to
27
+ BelongsToReflection
28
+ else
29
+ raise "Unsupported Macro: #{macro}"
30
+ end
29
31
 
30
32
  reflection = klass.new(name, scope, options, ar)
31
33
  options[:through] ? ThroughReflection.new(reflection) : reflection
@@ -135,8 +137,8 @@ module ActiveRecord
135
137
  # BelongsToReflection
136
138
  # HasAndBelongsToManyReflection
137
139
  # ThroughReflection
138
- # PolymorphicReflection
139
- # RuntimeReflection
140
+ # PolymorphicReflection
141
+ # RuntimeReflection
140
142
  class AbstractReflection # :nodoc:
141
143
  def through_reflection?
142
144
  false
@@ -174,8 +176,19 @@ module ActiveRecord
174
176
  JoinKeys.new(foreign_key, active_record_primary_key)
175
177
  end
176
178
 
179
+ # Returns a list of scopes that should be applied for this Reflection
180
+ # object when querying the database.
181
+ def scopes
182
+ scope ? [scope] : []
183
+ end
184
+
185
+ def scope_chain
186
+ chain.map(&:scopes)
187
+ end
188
+ deprecate :scope_chain
189
+
177
190
  def constraints
178
- scope_chain.flatten
191
+ chain.map(&:scopes).flatten
179
192
  end
180
193
 
181
194
  def counter_cache_column
@@ -281,7 +294,6 @@ module ActiveRecord
281
294
  end
282
295
 
283
296
  def autosave=(autosave)
284
- @automatic_inverse_of = false
285
297
  @options[:autosave] = autosave
286
298
  parent_reflection = self.parent_reflection
287
299
  if parent_reflection
@@ -321,8 +333,7 @@ module ActiveRecord
321
333
  end
322
334
  end
323
335
 
324
-
325
- # Holds all the meta-data about an aggregation as it was specified in the
336
+ # Holds all the metadata about an aggregation as it was specified in the
326
337
  # Active Record class.
327
338
  class AggregateReflection < MacroReflection #:nodoc:
328
339
  def mapping
@@ -331,7 +342,7 @@ module ActiveRecord
331
342
  end
332
343
  end
333
344
 
334
- # Holds all the meta-data about an association as it was specified in the
345
+ # Holds all the metadata about an association as it was specified in the
335
346
  # Active Record class.
336
347
  class AssociationReflection < MacroReflection #:nodoc:
337
348
  # Returns the target association's class.
@@ -365,6 +376,17 @@ module ActiveRecord
365
376
  @constructable = calculate_constructable(macro, options)
366
377
  @association_scope_cache = {}
367
378
  @scope_lock = Mutex.new
379
+
380
+ if options[:class_name] && options[:class_name].class == Class
381
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
382
+ Passing a class to the `class_name` is deprecated and will raise
383
+ an ArgumentError in Rails 5.2. It eagerloads more classes than
384
+ necessary and potentially creates circular dependencies.
385
+
386
+ Please pass the class name as a string:
387
+ `#{macro} :#{name}, class_name: '#{options[:class_name]}'`
388
+ MSG
389
+ end
368
390
  end
369
391
 
370
392
  def association_scope_cache(conn, owner)
@@ -451,12 +473,6 @@ module ActiveRecord
451
473
  false
452
474
  end
453
475
 
454
- # An array of arrays of scopes. Each item in the outside array corresponds to a reflection
455
- # in the #chain.
456
- def scope_chain
457
- scope ? [[scope]] : [[]]
458
- end
459
-
460
476
  def has_scope?
461
477
  scope
462
478
  end
@@ -527,10 +543,6 @@ module ActiveRecord
527
543
  seed + [self]
528
544
  end
529
545
 
530
- def extensions
531
- Array(options[:extend])
532
- end
533
-
534
546
  protected
535
547
 
536
548
  def actual_source_reflection # FIXME: this is a horrible name
@@ -545,14 +557,10 @@ module ActiveRecord
545
557
 
546
558
  # Attempts to find the inverse association name automatically.
547
559
  # If it cannot find a suitable inverse association name, it returns
548
- # nil.
560
+ # +nil+.
549
561
  def inverse_name
550
562
  options.fetch(:inverse_of) do
551
- if @automatic_inverse_of == false
552
- nil
553
- else
554
- @automatic_inverse_of ||= automatic_inverse_of
555
- end
563
+ @automatic_inverse_of ||= automatic_inverse_of
556
564
  end
557
565
  end
558
566
 
@@ -644,10 +652,6 @@ module ActiveRecord
644
652
  Associations::HasManyAssociation
645
653
  end
646
654
  end
647
-
648
- def association_primary_key(klass = nil)
649
- primary_key(klass || self.klass)
650
- end
651
655
  end
652
656
 
653
657
  class HasOneReflection < AssociationReflection # :nodoc:
@@ -711,16 +715,16 @@ module ActiveRecord
711
715
  end
712
716
  end
713
717
 
714
- # Holds all the meta-data about a :through association as it was specified
718
+ # Holds all the metadata about a :through association as it was specified
715
719
  # in the Active Record class.
716
720
  class ThroughReflection < AbstractReflection #:nodoc:
717
721
  attr_reader :delegate_reflection
718
722
  delegate :foreign_key, :foreign_type, :association_foreign_key,
719
- :active_record_primary_key, :type, :to => :source_reflection
723
+ :active_record_primary_key, :type, to: :source_reflection
720
724
 
721
725
  def initialize(delegate_reflection)
722
726
  @delegate_reflection = delegate_reflection
723
- @klass = delegate_reflection.options[:anonymous_class]
727
+ @klass = delegate_reflection.options[:anonymous_class]
724
728
  @source_reflection_name = delegate_reflection.options[:source]
725
729
  end
726
730
 
@@ -798,45 +802,12 @@ module ActiveRecord
798
802
  through_reflection.clear_association_scope_cache
799
803
  end
800
804
 
801
- # Consider the following example:
802
- #
803
- # class Person
804
- # has_many :articles
805
- # has_many :comment_tags, through: :articles
806
- # end
807
- #
808
- # class Article
809
- # has_many :comments
810
- # has_many :comment_tags, through: :comments, source: :tags
811
- # end
812
- #
813
- # class Comment
814
- # has_many :tags
815
- # end
816
- #
817
- # There may be scopes on Person.comment_tags, Article.comment_tags and/or Comment.tags,
818
- # but only Comment.tags will be represented in the #chain. So this method creates an array
819
- # of scopes corresponding to the chain.
820
- def scope_chain
821
- @scope_chain ||= begin
822
- scope_chain = source_reflection.scope_chain.map(&:dup)
823
-
824
- # Add to it the scope from this reflection (if any)
825
- scope_chain.first << scope if scope
826
-
827
- through_scope_chain = through_reflection.scope_chain.map(&:dup)
828
-
829
- if options[:source_type]
830
- type = foreign_type
831
- source_type = options[:source_type]
832
- through_scope_chain.first << lambda { |object|
833
- where(type => source_type)
834
- }
835
- end
805
+ def scopes
806
+ source_reflection.scopes + super
807
+ end
836
808
 
837
- # Recursively fill out the rest of the array from the through reflection
838
- scope_chain + through_scope_chain
839
- end
809
+ def source_type_scope
810
+ through_reflection.klass.where(foreign_type => options[:source_type])
840
811
  end
841
812
 
842
813
  def has_scope?
@@ -891,15 +862,13 @@ module ActiveRecord
891
862
  }
892
863
 
893
864
  if names.length > 1
894
- example_options = options.dup
895
- example_options[:source] = source_reflection_names.first
896
- ActiveSupport::Deprecation.warn \
897
- "Ambiguous source reflection for through association. Please " \
898
- "specify a :source directive on your declaration like:\n" \
899
- "\n" \
900
- " class #{active_record.name} < ActiveRecord::Base\n" \
901
- " #{macro} :#{name}, #{example_options}\n" \
902
- " end"
865
+ raise AmbiguousSourceReflectionForThroughAssociation.new(
866
+ active_record.name,
867
+ macro,
868
+ name,
869
+ options,
870
+ source_reflection_names
871
+ )
903
872
  end
904
873
 
905
874
  @source_reflection_name = names.first
@@ -946,6 +915,14 @@ module ActiveRecord
946
915
  raise HasOneThroughCantAssociateThroughCollection.new(active_record.name, self, through_reflection)
947
916
  end
948
917
 
918
+ if parent_reflection.nil?
919
+ reflections = active_record.reflections.keys.map(&:to_sym)
920
+
921
+ if reflections.index(through_reflection.name) > reflections.index(name)
922
+ raise HasManyThroughOrderError.new(active_record.name, self, through_reflection)
923
+ end
924
+ end
925
+
949
926
  check_validity_of_inverse!
950
927
  end
951
928
 
@@ -976,8 +953,7 @@ module ActiveRecord
976
953
  end
977
954
  end
978
955
 
979
- protected
980
-
956
+ private
981
957
  def actual_source_reflection # FIXME: this is a horrible name
982
958
  source_reflection.send(:actual_source_reflection)
983
959
  end
@@ -988,7 +964,6 @@ module ActiveRecord
988
964
 
989
965
  def inverse_name; delegate_reflection.send(:inverse_name); end
990
966
 
991
- private
992
967
  def derive_class_name
993
968
  # get the class_name of the belongs_to association of the through reflection
994
969
  options[:source_type] || source_reflection.class_name
@@ -998,15 +973,23 @@ module ActiveRecord
998
973
  public_instance_methods
999
974
 
1000
975
  delegate(*delegate_methods, to: :delegate_reflection)
1001
-
1002
976
  end
1003
977
 
1004
- class PolymorphicReflection < ThroughReflection # :nodoc:
978
+ class PolymorphicReflection < AbstractReflection # :nodoc:
1005
979
  def initialize(reflection, previous_reflection)
1006
980
  @reflection = reflection
1007
981
  @previous_reflection = previous_reflection
1008
982
  end
1009
983
 
984
+ def scopes
985
+ scopes = @previous_reflection.scopes
986
+ if @previous_reflection.options[:source_type]
987
+ scopes + [@previous_reflection.source_type_scope]
988
+ else
989
+ scopes
990
+ end
991
+ end
992
+
1010
993
  def klass
1011
994
  @reflection.klass
1012
995
  end
@@ -1,5 +1,3 @@
1
- require "arel/collectors/bind"
2
-
3
1
  module ActiveRecord
4
2
  # = Active Record \Relation
5
3
  class Relation
@@ -31,9 +29,7 @@ module ActiveRecord
31
29
  end
32
30
 
33
31
  def initialize_copy(other)
34
- # This method is a hot spot, so for now, use Hash[] to dup the hash.
35
- # https://bugs.ruby-lang.org/issues/7166
36
- @values = Hash[@values]
32
+ @values = @values.dup
37
33
  reset
38
34
  end
39
35
 
@@ -64,8 +60,8 @@ module ActiveRecord
64
60
 
65
61
  @klass.connection.insert(
66
62
  im,
67
- 'SQL',
68
- primary_key,
63
+ "SQL",
64
+ primary_key || false,
69
65
  primary_key_value,
70
66
  nil,
71
67
  binds)
@@ -88,7 +84,7 @@ module ActiveRecord
88
84
 
89
85
  @klass.connection.update(
90
86
  um,
91
- 'SQL',
87
+ "SQL",
92
88
  bvs,
93
89
  )
94
90
  end
@@ -247,7 +243,6 @@ module ActiveRecord
247
243
  # Please see further details in the
248
244
  # {Active Record Query Interface guide}[http://guides.rubyonrails.org/active_record_querying.html#running-explain].
249
245
  def explain
250
- #TODO: Fix for binds.
251
246
  exec_explain(collecting_queries_for_explain { exec_queries })
252
247
  end
253
248
 
@@ -279,12 +274,7 @@ module ActiveRecord
279
274
  def empty?
280
275
  return @records.empty? if loaded?
281
276
 
282
- if limit_value == 0
283
- true
284
- else
285
- c = count(:all)
286
- c.respond_to?(:zero?) ? c.zero? : c.empty?
287
- end
277
+ limit_value == 0 || !exists?
288
278
  end
289
279
 
290
280
  # Returns true if there are no records.
@@ -347,7 +337,7 @@ module ActiveRecord
347
337
  # Please check unscoped if you want to remove all previous scopes (including
348
338
  # the default_scope) during the execution of a block.
349
339
  def scoping
350
- previous, klass.current_scope = klass.current_scope(true), self
340
+ previous, klass.current_scope = klass.current_scope, self
351
341
  yield
352
342
  ensure
353
343
  klass.current_scope = previous
@@ -383,7 +373,7 @@ module ActiveRecord
383
373
  stmt.set Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates))
384
374
  stmt.table(table)
385
375
 
386
- if joins_values.any?
376
+ if has_join_values?
387
377
  @klass.connection.join_to_update(stmt, arel, arel_attribute(primary_key))
388
378
  else
389
379
  stmt.key = arel_attribute(primary_key)
@@ -392,7 +382,7 @@ module ActiveRecord
392
382
  stmt.wheres = arel.constraints
393
383
  end
394
384
 
395
- @klass.connection.update stmt, 'SQL', bound_attributes
385
+ @klass.connection.update stmt, "SQL", bound_attributes
396
386
  end
397
387
 
398
388
  # Updates an object (or multiple objects) and saves it to the database, if validations pass.
@@ -428,8 +418,7 @@ module ActiveRecord
428
418
  records.each { |record| record.update(attributes) }
429
419
  else
430
420
  if ActiveRecord::Base === id
431
- id = id.id
432
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
421
+ raise ArgumentError, <<-MSG.squish
433
422
  You are passing an instance of ActiveRecord::Base to `update`.
434
423
  Please pass the id of the object by calling `.id`.
435
424
  MSG
@@ -456,16 +445,8 @@ module ActiveRecord
456
445
  # ==== Examples
457
446
  #
458
447
  # Person.where(age: 0..18).destroy_all
459
- def destroy_all(conditions = nil)
460
- if conditions
461
- ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
462
- Passing conditions to destroy_all is deprecated and will be removed in Rails 5.1.
463
- To achieve the same use where(conditions).destroy_all.
464
- MESSAGE
465
- where(conditions).destroy_all
466
- else
467
- records.each(&:destroy).tap { reset }
468
- end
448
+ def destroy_all
449
+ records.each(&:destroy).tap { reset }
469
450
  end
470
451
 
471
452
  # Destroy an object (or multiple objects) that has the given id. The object is instantiated first,
@@ -513,41 +494,28 @@ module ActiveRecord
513
494
  #
514
495
  # Post.limit(100).delete_all
515
496
  # # => ActiveRecord::ActiveRecordError: delete_all doesn't support limit
516
- def delete_all(conditions = nil)
517
- invalid_methods = INVALID_METHODS_FOR_DELETE_ALL.select { |method|
518
- if MULTI_VALUE_METHODS.include?(method)
519
- send("#{method}_values").any?
520
- elsif SINGLE_VALUE_METHODS.include?(method)
521
- send("#{method}_value")
522
- elsif CLAUSE_METHODS.include?(method)
523
- send("#{method}_clause").any?
524
- end
525
- }
497
+ def delete_all
498
+ invalid_methods = INVALID_METHODS_FOR_DELETE_ALL.select do |method|
499
+ value = get_value(method)
500
+ SINGLE_VALUE_METHODS.include?(method) ? value : value.any?
501
+ end
526
502
  if invalid_methods.any?
527
503
  raise ActiveRecordError.new("delete_all doesn't support #{invalid_methods.join(', ')}")
528
504
  end
529
505
 
530
- if conditions
531
- ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
532
- Passing conditions to delete_all is deprecated and will be removed in Rails 5.1.
533
- To achieve the same use where(conditions).delete_all.
534
- MESSAGE
535
- where(conditions).delete_all
536
- else
537
- stmt = Arel::DeleteManager.new
538
- stmt.from(table)
506
+ stmt = Arel::DeleteManager.new
507
+ stmt.from(table)
539
508
 
540
- if joins_values.any?
541
- @klass.connection.join_to_delete(stmt, arel, arel_attribute(primary_key))
542
- else
543
- stmt.wheres = arel.constraints
544
- end
509
+ if has_join_values?
510
+ @klass.connection.join_to_delete(stmt, arel, arel_attribute(primary_key))
511
+ else
512
+ stmt.wheres = arel.constraints
513
+ end
545
514
 
546
- affected = @klass.connection.delete(stmt, 'SQL', bound_attributes)
515
+ affected = @klass.connection.delete(stmt, "SQL", bound_attributes)
547
516
 
548
- reset
549
- affected
550
- end
517
+ reset
518
+ affected
551
519
  end
552
520
 
553
521
  # Deletes the row with a primary key matching the +id+ argument, using a
@@ -605,19 +573,16 @@ module ActiveRecord
605
573
  # # => SELECT "users".* FROM "users" WHERE "users"."name" = 'Oscar'
606
574
  def to_sql
607
575
  @to_sql ||= begin
608
- relation = self
609
- connection = klass.connection
610
- visitor = connection.visitor
576
+ relation = self
611
577
 
612
578
  if eager_loading?
613
579
  find_with_associations { |rel| relation = rel }
614
580
  end
615
581
 
616
- binds = relation.bound_attributes
617
- binds = connection.prepare_binds_for_database(binds)
618
- binds.map! { |value| connection.quote(value) }
619
- collect = visitor.accept(relation.arel.ast, Arel::Collectors::Bind.new)
620
- collect.substitute_binds(binds).join
582
+ conn = klass.connection
583
+ conn.unprepared_statement {
584
+ conn.to_sql(relation.arel, relation.bound_attributes)
585
+ }
621
586
  end
622
587
  end
623
588
 
@@ -648,15 +613,6 @@ module ActiveRecord
648
613
  includes_values & joins_values
649
614
  end
650
615
 
651
- # {#uniq}[rdoc-ref:QueryMethods#uniq] and
652
- # {#uniq!}[rdoc-ref:QueryMethods#uniq!] are silently deprecated.
653
- # #uniq_value delegates to #distinct_value to maintain backwards compatibility.
654
- # Use #distinct_value instead.
655
- def uniq_value
656
- distinct_value
657
- end
658
- deprecate uniq_value: :distinct_value
659
-
660
616
  # Compares two relations for equality.
661
617
  def ==(other)
662
618
  case other
@@ -670,7 +626,7 @@ module ActiveRecord
670
626
  end
671
627
 
672
628
  def pretty_print(q)
673
- q.pp(self.records)
629
+ q.pp(records)
674
630
  end
675
631
 
676
632
  # Returns true if relation is blank.
@@ -679,20 +635,16 @@ module ActiveRecord
679
635
  end
680
636
 
681
637
  def values
682
- Hash[@values]
638
+ @values.dup
683
639
  end
684
640
 
685
641
  def inspect
686
642
  entries = records.take([limit_value, 11].compact.min).map!(&:inspect)
687
- entries[10] = '...' if entries.size == 11
643
+ entries[10] = "..." if entries.size == 11
688
644
 
689
645
  "#<#{self.class.name} [#{entries.join(', ')}]>"
690
646
  end
691
647
 
692
- def empty_scope? # :nodoc:
693
- @values == klass.unscoped.values
694
- end
695
-
696
648
  protected
697
649
 
698
650
  def load_records(records)
@@ -702,48 +654,53 @@ module ActiveRecord
702
654
 
703
655
  private
704
656
 
705
- def exec_queries(&block)
706
- @records = eager_loading? ? find_with_associations.freeze : @klass.find_by_sql(arel, bound_attributes, &block).freeze
707
-
708
- preload = preload_values
709
- preload += includes_values unless eager_loading?
710
- preloader = build_preloader
711
- preload.each do |associations|
712
- preloader.preload @records, associations
657
+ def has_join_values?
658
+ joins_values.any? || left_outer_joins_values.any?
713
659
  end
714
660
 
715
- @records.each(&:readonly!) if readonly_value
661
+ def exec_queries(&block)
662
+ @records = eager_loading? ? find_with_associations.freeze : @klass.find_by_sql(arel, bound_attributes, &block).freeze
716
663
 
717
- @loaded = true
718
- @records
719
- end
664
+ preload = preload_values
665
+ preload += includes_values unless eager_loading?
666
+ preloader = nil
667
+ preload.each do |associations|
668
+ preloader ||= build_preloader
669
+ preloader.preload @records, associations
670
+ end
720
671
 
721
- def build_preloader
722
- ActiveRecord::Associations::Preloader.new
723
- end
672
+ @records.each(&:readonly!) if readonly_value
724
673
 
725
- def references_eager_loaded_tables?
726
- joined_tables = arel.join_sources.map do |join|
727
- if join.is_a?(Arel::Nodes::StringJoin)
728
- tables_in_string(join.left)
729
- else
730
- [join.left.table_name, join.left.table_alias]
731
- end
674
+ @loaded = true
675
+ @records
732
676
  end
733
677
 
734
- joined_tables += [table.name, table.table_alias]
678
+ def build_preloader
679
+ ActiveRecord::Associations::Preloader.new
680
+ end
735
681
 
736
- # always convert table names to downcase as in Oracle quoted table names are in uppercase
737
- joined_tables = joined_tables.flatten.compact.map(&:downcase).uniq
682
+ def references_eager_loaded_tables?
683
+ joined_tables = arel.join_sources.map do |join|
684
+ if join.is_a?(Arel::Nodes::StringJoin)
685
+ tables_in_string(join.left)
686
+ else
687
+ [join.left.table_name, join.left.table_alias]
688
+ end
689
+ end
738
690
 
739
- (references_values - joined_tables).any?
740
- end
691
+ joined_tables += [table.name, table.table_alias]
741
692
 
742
- def tables_in_string(string)
743
- return [] if string.blank?
744
- # always convert table names to downcase as in Oracle quoted table names are in uppercase
745
- # ignore raw_sql_ that is used by Oracle adapter as alias for limit/offset subqueries
746
- string.scan(/([a-zA-Z_][.\w]+).?\./).flatten.map(&:downcase).uniq - ['raw_sql_']
747
- end
693
+ # always convert table names to downcase as in Oracle quoted table names are in uppercase
694
+ joined_tables = joined_tables.flatten.compact.map(&:downcase).uniq
695
+
696
+ (references_values - joined_tables).any?
697
+ end
698
+
699
+ def tables_in_string(string)
700
+ return [] if string.blank?
701
+ # always convert table names to downcase as in Oracle quoted table names are in uppercase
702
+ # ignore raw_sql_ that is used by Oracle adapter as alias for limit/offset subqueries
703
+ string.scan(/([a-zA-Z_][.\w]+).?\./).flatten.map(&:downcase).uniq - ["raw_sql_"]
704
+ end
748
705
  end
749
706
  end