activerecord 5.2.7 → 6.0.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 (241) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +299 -778
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +4 -2
  7. data/lib/active_record/associations/association.rb +35 -19
  8. data/lib/active_record/associations/association_scope.rb +4 -6
  9. data/lib/active_record/associations/belongs_to_association.rb +36 -42
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
  11. data/lib/active_record/associations/builder/belongs_to.rb +14 -50
  12. data/lib/active_record/associations/builder/collection_association.rb +3 -3
  13. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
  14. data/lib/active_record/associations/collection_association.rb +11 -25
  15. data/lib/active_record/associations/collection_proxy.rb +32 -6
  16. data/lib/active_record/associations/foreign_association.rb +7 -0
  17. data/lib/active_record/associations/has_many_association.rb +1 -1
  18. data/lib/active_record/associations/has_many_through_association.rb +25 -18
  19. data/lib/active_record/associations/has_one_association.rb +28 -30
  20. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  21. data/lib/active_record/associations/join_dependency/join_association.rb +11 -26
  22. data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
  23. data/lib/active_record/associations/join_dependency.rb +15 -20
  24. data/lib/active_record/associations/preloader/association.rb +1 -2
  25. data/lib/active_record/associations/preloader.rb +32 -29
  26. data/lib/active_record/associations/singular_association.rb +2 -16
  27. data/lib/active_record/associations.rb +16 -12
  28. data/lib/active_record/attribute_assignment.rb +7 -10
  29. data/lib/active_record/attribute_methods/dirty.rb +64 -26
  30. data/lib/active_record/attribute_methods/primary_key.rb +8 -7
  31. data/lib/active_record/attribute_methods/read.rb +16 -48
  32. data/lib/active_record/attribute_methods/serialization.rb +1 -1
  33. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
  34. data/lib/active_record/attribute_methods/write.rb +15 -16
  35. data/lib/active_record/attribute_methods.rb +34 -56
  36. data/lib/active_record/autosave_association.rb +7 -21
  37. data/lib/active_record/base.rb +2 -2
  38. data/lib/active_record/callbacks.rb +3 -17
  39. data/lib/active_record/collection_cache_key.rb +1 -1
  40. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +13 -36
  41. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  42. data/lib/active_record/connection_adapters/abstract/database_statements.rb +25 -84
  43. data/lib/active_record/connection_adapters/abstract/query_cache.rb +17 -14
  44. data/lib/active_record/connection_adapters/abstract/quoting.rb +5 -11
  45. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -11
  46. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +30 -13
  47. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +0 -2
  48. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +41 -27
  49. data/lib/active_record/connection_adapters/abstract/transaction.rb +81 -52
  50. data/lib/active_record/connection_adapters/abstract_adapter.rb +95 -31
  51. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +65 -90
  52. data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
  53. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +5 -9
  54. data/lib/active_record/connection_adapters/mysql/database_statements.rb +29 -7
  55. data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
  56. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
  57. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +65 -10
  58. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -4
  59. data/lib/active_record/connection_adapters/postgresql/column.rb +1 -2
  60. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +16 -1
  61. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  62. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  63. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
  64. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
  65. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  66. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
  67. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  68. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  69. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +11 -36
  70. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +9 -2
  71. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +38 -20
  72. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -1
  73. data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -56
  74. data/lib/active_record/connection_adapters/schema_cache.rb +5 -0
  75. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +5 -5
  76. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +14 -9
  77. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +95 -62
  78. data/lib/active_record/connection_handling.rb +132 -26
  79. data/lib/active_record/core.rb +76 -43
  80. data/lib/active_record/counter_cache.rb +4 -29
  81. data/lib/active_record/database_configurations/database_config.rb +37 -0
  82. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  83. data/lib/active_record/database_configurations/url_config.rb +74 -0
  84. data/lib/active_record/database_configurations.rb +184 -0
  85. data/lib/active_record/enum.rb +22 -7
  86. data/lib/active_record/errors.rb +24 -21
  87. data/lib/active_record/explain.rb +1 -1
  88. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  89. data/lib/active_record/fixture_set/render_context.rb +17 -0
  90. data/lib/active_record/fixture_set/table_row.rb +153 -0
  91. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  92. data/lib/active_record/fixtures.rb +140 -472
  93. data/lib/active_record/gem_version.rb +4 -4
  94. data/lib/active_record/inheritance.rb +12 -2
  95. data/lib/active_record/integration.rb +56 -16
  96. data/lib/active_record/internal_metadata.rb +5 -1
  97. data/lib/active_record/locking/optimistic.rb +2 -2
  98. data/lib/active_record/locking/pessimistic.rb +3 -3
  99. data/lib/active_record/log_subscriber.rb +7 -26
  100. data/lib/active_record/migration/command_recorder.rb +35 -5
  101. data/lib/active_record/migration/compatibility.rb +34 -16
  102. data/lib/active_record/migration.rb +38 -37
  103. data/lib/active_record/model_schema.rb +30 -9
  104. data/lib/active_record/nested_attributes.rb +2 -2
  105. data/lib/active_record/no_touching.rb +7 -0
  106. data/lib/active_record/persistence.rb +18 -7
  107. data/lib/active_record/query_cache.rb +11 -4
  108. data/lib/active_record/querying.rb +19 -11
  109. data/lib/active_record/railtie.rb +71 -42
  110. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  111. data/lib/active_record/railties/controller_runtime.rb +30 -35
  112. data/lib/active_record/railties/databases.rake +94 -43
  113. data/lib/active_record/reflection.rb +60 -44
  114. data/lib/active_record/relation/batches.rb +13 -10
  115. data/lib/active_record/relation/calculations.rb +38 -28
  116. data/lib/active_record/relation/delegation.rb +4 -13
  117. data/lib/active_record/relation/finder_methods.rb +12 -25
  118. data/lib/active_record/relation/merger.rb +2 -6
  119. data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
  120. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  121. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  122. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  123. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  124. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  125. data/lib/active_record/relation/predicate_builder.rb +4 -6
  126. data/lib/active_record/relation/query_attribute.rb +15 -12
  127. data/lib/active_record/relation/query_methods.rb +29 -52
  128. data/lib/active_record/relation/where_clause.rb +4 -0
  129. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  130. data/lib/active_record/relation.rb +150 -69
  131. data/lib/active_record/result.rb +30 -11
  132. data/lib/active_record/sanitization.rb +2 -39
  133. data/lib/active_record/schema.rb +1 -10
  134. data/lib/active_record/schema_dumper.rb +12 -6
  135. data/lib/active_record/schema_migration.rb +4 -0
  136. data/lib/active_record/scoping/default.rb +10 -3
  137. data/lib/active_record/scoping/named.rb +10 -14
  138. data/lib/active_record/scoping.rb +9 -8
  139. data/lib/active_record/statement_cache.rb +32 -5
  140. data/lib/active_record/store.rb +39 -8
  141. data/lib/active_record/table_metadata.rb +1 -4
  142. data/lib/active_record/tasks/database_tasks.rb +89 -23
  143. data/lib/active_record/tasks/mysql_database_tasks.rb +2 -4
  144. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
  145. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
  146. data/lib/active_record/test_databases.rb +38 -0
  147. data/lib/active_record/test_fixtures.rb +224 -0
  148. data/lib/active_record/timestamp.rb +4 -6
  149. data/lib/active_record/transactions.rb +3 -22
  150. data/lib/active_record/translation.rb +1 -1
  151. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  152. data/lib/active_record/type.rb +3 -4
  153. data/lib/active_record/type_caster/connection.rb +1 -6
  154. data/lib/active_record/type_caster/map.rb +1 -4
  155. data/lib/active_record/validations/uniqueness.rb +13 -25
  156. data/lib/active_record.rb +2 -1
  157. data/lib/arel/alias_predication.rb +9 -0
  158. data/lib/arel/attributes/attribute.rb +37 -0
  159. data/lib/arel/attributes.rb +22 -0
  160. data/lib/arel/collectors/bind.rb +24 -0
  161. data/lib/arel/collectors/composite.rb +31 -0
  162. data/lib/arel/collectors/plain_string.rb +20 -0
  163. data/lib/arel/collectors/sql_string.rb +20 -0
  164. data/lib/arel/collectors/substitute_binds.rb +28 -0
  165. data/lib/arel/crud.rb +42 -0
  166. data/lib/arel/delete_manager.rb +18 -0
  167. data/lib/arel/errors.rb +9 -0
  168. data/lib/arel/expressions.rb +29 -0
  169. data/lib/arel/factory_methods.rb +49 -0
  170. data/lib/arel/insert_manager.rb +49 -0
  171. data/lib/arel/math.rb +45 -0
  172. data/lib/arel/nodes/and.rb +32 -0
  173. data/lib/arel/nodes/ascending.rb +23 -0
  174. data/lib/arel/nodes/binary.rb +52 -0
  175. data/lib/arel/nodes/bind_param.rb +36 -0
  176. data/lib/arel/nodes/case.rb +55 -0
  177. data/lib/arel/nodes/casted.rb +50 -0
  178. data/lib/arel/nodes/count.rb +12 -0
  179. data/lib/arel/nodes/delete_statement.rb +45 -0
  180. data/lib/arel/nodes/descending.rb +23 -0
  181. data/lib/arel/nodes/equality.rb +18 -0
  182. data/lib/arel/nodes/extract.rb +24 -0
  183. data/lib/arel/nodes/false.rb +16 -0
  184. data/lib/arel/nodes/full_outer_join.rb +8 -0
  185. data/lib/arel/nodes/function.rb +44 -0
  186. data/lib/arel/nodes/grouping.rb +8 -0
  187. data/lib/arel/nodes/in.rb +8 -0
  188. data/lib/arel/nodes/infix_operation.rb +80 -0
  189. data/lib/arel/nodes/inner_join.rb +8 -0
  190. data/lib/arel/nodes/insert_statement.rb +37 -0
  191. data/lib/arel/nodes/join_source.rb +20 -0
  192. data/lib/arel/nodes/matches.rb +18 -0
  193. data/lib/arel/nodes/named_function.rb +23 -0
  194. data/lib/arel/nodes/node.rb +50 -0
  195. data/lib/arel/nodes/node_expression.rb +13 -0
  196. data/lib/arel/nodes/outer_join.rb +8 -0
  197. data/lib/arel/nodes/over.rb +15 -0
  198. data/lib/arel/nodes/regexp.rb +16 -0
  199. data/lib/arel/nodes/right_outer_join.rb +8 -0
  200. data/lib/arel/nodes/select_core.rb +63 -0
  201. data/lib/arel/nodes/select_statement.rb +41 -0
  202. data/lib/arel/nodes/sql_literal.rb +16 -0
  203. data/lib/arel/nodes/string_join.rb +11 -0
  204. data/lib/arel/nodes/table_alias.rb +27 -0
  205. data/lib/arel/nodes/terminal.rb +16 -0
  206. data/lib/arel/nodes/true.rb +16 -0
  207. data/lib/arel/nodes/unary.rb +44 -0
  208. data/lib/arel/nodes/unary_operation.rb +20 -0
  209. data/lib/arel/nodes/unqualified_column.rb +22 -0
  210. data/lib/arel/nodes/update_statement.rb +41 -0
  211. data/lib/arel/nodes/values.rb +16 -0
  212. data/lib/arel/nodes/values_list.rb +24 -0
  213. data/lib/arel/nodes/window.rb +126 -0
  214. data/lib/arel/nodes/with.rb +11 -0
  215. data/lib/arel/nodes.rb +67 -0
  216. data/lib/arel/order_predications.rb +13 -0
  217. data/lib/arel/predications.rb +257 -0
  218. data/lib/arel/select_manager.rb +271 -0
  219. data/lib/arel/table.rb +110 -0
  220. data/lib/arel/tree_manager.rb +72 -0
  221. data/lib/arel/update_manager.rb +34 -0
  222. data/lib/arel/visitors/depth_first.rb +199 -0
  223. data/lib/arel/visitors/dot.rb +292 -0
  224. data/lib/arel/visitors/ibm_db.rb +21 -0
  225. data/lib/arel/visitors/informix.rb +56 -0
  226. data/lib/arel/visitors/mssql.rb +143 -0
  227. data/lib/arel/visitors/mysql.rb +83 -0
  228. data/lib/arel/visitors/oracle.rb +159 -0
  229. data/lib/arel/visitors/oracle12.rb +67 -0
  230. data/lib/arel/visitors/postgresql.rb +116 -0
  231. data/lib/arel/visitors/sqlite.rb +39 -0
  232. data/lib/arel/visitors/to_sql.rb +913 -0
  233. data/lib/arel/visitors/visitor.rb +42 -0
  234. data/lib/arel/visitors/where_sql.rb +23 -0
  235. data/lib/arel/visitors.rb +20 -0
  236. data/lib/arel/window_predications.rb +9 -0
  237. data/lib/arel.rb +44 -0
  238. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  239. data/lib/rails/generators/active_record/migration.rb +14 -1
  240. data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
  241. metadata +104 -26
@@ -79,17 +79,12 @@ module ActiveRecord
79
79
  # Post.find_by "published_at < ?", 2.weeks.ago
80
80
  def find_by(arg, *args)
81
81
  where(arg, *args).take
82
- rescue ::RangeError
83
- nil
84
82
  end
85
83
 
86
84
  # Like #find_by, except that if no record is found, raises
87
85
  # an ActiveRecord::RecordNotFound error.
88
86
  def find_by!(arg, *args)
89
87
  where(arg, *args).take!
90
- rescue ::RangeError
91
- raise RecordNotFound.new("Couldn't find #{@klass.name} with an out of range value",
92
- @klass.name, @klass.primary_key)
93
88
  end
94
89
 
95
90
  # Gives a record (or N records if a parameter is supplied) without any implied
@@ -312,6 +307,8 @@ module ActiveRecord
312
307
 
313
308
  return false if !conditions || limit_value == 0
314
309
 
310
+ conditions = sanitize_forbidden_attributes(conditions)
311
+
315
312
  if eager_loading?
316
313
  relation = apply_join_dependency(eager_loading: false)
317
314
  return relation.exists?(conditions)
@@ -319,9 +316,7 @@ module ActiveRecord
319
316
 
320
317
  relation = construct_relation_for_exists(conditions)
321
318
 
322
- skip_query_cache_if_necessary { connection.select_one(relation.arel, "#{name} Exists") } ? true : false
323
- rescue ::RangeError
324
- false
319
+ skip_query_cache_if_necessary { connection.select_value(relation.arel, "#{name} Exists") } ? true : false
325
320
  end
326
321
 
327
322
  # This method is called whenever no records are found with either a single
@@ -338,14 +333,14 @@ module ActiveRecord
338
333
  name = @klass.name
339
334
 
340
335
  if ids.nil?
341
- error = "Couldn't find #{name}".dup
336
+ error = +"Couldn't find #{name}"
342
337
  error << " with#{conditions}" if conditions
343
338
  raise RecordNotFound.new(error, name, key)
344
339
  elsif Array(ids).size == 1
345
340
  error = "Couldn't find #{name} with '#{key}'=#{ids}#{conditions}"
346
341
  raise RecordNotFound.new(error, name, key, ids)
347
342
  else
348
- error = "Couldn't find all #{name.pluralize} with '#{key}': ".dup
343
+ error = +"Couldn't find all #{name.pluralize} with '#{key}': "
349
344
  error << "(#{ids.join(", ")})#{conditions} (found #{result_size} results, but was looking for #{expected_size})."
350
345
  error << " Couldn't find #{name.pluralize(not_found_ids.size)} with #{key.to_s.pluralize(not_found_ids.size)} #{not_found_ids.join(', ')}." if not_found_ids
351
346
  raise RecordNotFound.new(error, name, key, ids)
@@ -359,11 +354,7 @@ module ActiveRecord
359
354
  end
360
355
 
361
356
  def construct_relation_for_exists(conditions)
362
- if distinct_value && offset_value
363
- relation = except(:order).limit!(1)
364
- else
365
- relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
366
- end
357
+ relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
367
358
 
368
359
  case conditions
369
360
  when Array, Hash
@@ -375,15 +366,14 @@ module ActiveRecord
375
366
  relation
376
367
  end
377
368
 
378
- def construct_join_dependency
379
- including = eager_load_values + includes_values
369
+ def construct_join_dependency(associations)
380
370
  ActiveRecord::Associations::JoinDependency.new(
381
- klass, table, including
371
+ klass, table, associations
382
372
  )
383
373
  end
384
374
 
385
375
  def apply_join_dependency(eager_loading: group_values.empty?)
386
- join_dependency = construct_join_dependency
376
+ join_dependency = construct_join_dependency(eager_load_values + includes_values)
387
377
  relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
388
378
 
389
379
  if eager_loading && !using_limitable_reflections?(join_dependency.reflections)
@@ -403,7 +393,7 @@ module ActiveRecord
403
393
 
404
394
  def limited_ids_for(relation)
405
395
  values = @klass.connection.columns_for_distinct(
406
- connection.column_name_from_arel_node(arel_attribute(primary_key)),
396
+ connection.visitor.compile(arel_attribute(primary_key)),
407
397
  relation.order_values
408
398
  )
409
399
 
@@ -437,9 +427,6 @@ module ActiveRecord
437
427
  else
438
428
  find_some(ids)
439
429
  end
440
- rescue ::RangeError
441
- error_message = "Couldn't find #{model_name} with an out of range ID"
442
- raise RecordNotFound.new(error_message, model_name, primary_key, ids)
443
430
  end
444
431
 
445
432
  def find_one(id)
@@ -555,8 +542,8 @@ module ActiveRecord
555
542
  end
556
543
 
557
544
  def ordered_relation
558
- if order_values.empty? && primary_key
559
- order(arel_attribute(primary_key).asc)
545
+ if order_values.empty? && (implicit_order_column || primary_key)
546
+ order(arel_attribute(implicit_order_column || primary_key).asc)
560
547
  else
561
548
  self
562
549
  end
@@ -120,9 +120,7 @@ module ActiveRecord
120
120
  joins_dependency = other.joins_values.map do |join|
121
121
  case join
122
122
  when Hash, Symbol, Array
123
- ActiveRecord::Associations::JoinDependency.new(
124
- other.klass, other.table, join
125
- )
123
+ other.send(:construct_join_dependency, join)
126
124
  else
127
125
  join
128
126
  end
@@ -141,9 +139,7 @@ module ActiveRecord
141
139
  joins_dependency = other.left_outer_joins_values.map do |join|
142
140
  case join
143
141
  when Hash, Symbol, Array
144
- ActiveRecord::Associations::JoinDependency.new(
145
- other.klass, other.table, join
146
- )
142
+ other.send(:construct_join_dependency, join)
147
143
  else
148
144
  join
149
145
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/array/extract"
4
+
3
5
  module ActiveRecord
4
6
  class PredicateBuilder
5
7
  class ArrayHandler # :nodoc:
@@ -11,8 +13,8 @@ module ActiveRecord
11
13
  return attribute.in([]) if value.empty?
12
14
 
13
15
  values = value.map { |x| x.is_a?(Base) ? x.id : x }
14
- nils, values = values.partition(&:nil?)
15
- ranges, values = values.partition { |v| v.is_a?(Range) }
16
+ nils = values.extract!(&:nil?)
17
+ ranges = values.extract! { |v| v.is_a?(Range) }
16
18
 
17
19
  values_predicate =
18
20
  case values.length
@@ -34,8 +36,7 @@ module ActiveRecord
34
36
  array_predicates.inject(&:or)
35
37
  end
36
38
 
37
- protected
38
-
39
+ private
39
40
  attr_reader :predicate_builder
40
41
 
41
42
  module NullPredicate # :nodoc:
@@ -12,12 +12,9 @@ module ActiveRecord
12
12
  [associated_table.association_join_foreign_key.to_s => ids]
13
13
  end
14
14
 
15
- # TODO Change this to private once we've dropped Ruby 2.2 support.
16
- # Workaround for Ruby 2.2 "private attribute?" warning.
17
- protected
15
+ private
18
16
  attr_reader :associated_table, :value
19
17
 
20
- private
21
18
  def ids
22
19
  case value
23
20
  when Relation
@@ -11,8 +11,7 @@ module ActiveRecord
11
11
  predicate_builder.build(attribute, value.id)
12
12
  end
13
13
 
14
- protected
15
-
14
+ private
16
15
  attr_reader :predicate_builder
17
16
  end
18
17
  end
@@ -12,8 +12,7 @@ module ActiveRecord
12
12
  attribute.eq(bind)
13
13
  end
14
14
 
15
- protected
16
-
15
+ private
17
16
  attr_reader :predicate_builder
18
17
  end
19
18
  end
@@ -17,12 +17,9 @@ module ActiveRecord
17
17
  end
18
18
  end
19
19
 
20
- # TODO Change this to private once we've dropped Ruby 2.2 support.
21
- # Workaround for Ruby 2.2 "private attribute?" warning.
22
- protected
20
+ private
23
21
  attr_reader :associated_table, :values
24
22
 
25
- private
26
23
  def type_to_ids_mapping
27
24
  default_hash = Hash.new { |hsh, key| hsh[key] = [] }
28
25
  values.each_with_object(default_hash) do |value, hash|
@@ -3,11 +3,7 @@
3
3
  module ActiveRecord
4
4
  class PredicateBuilder
5
5
  class RangeHandler # :nodoc:
6
- class RangeWithBinds < Struct.new(:begin, :end)
7
- def exclude_end?
8
- false
9
- end
10
- end
6
+ RangeWithBinds = Struct.new(:begin, :end, :exclude_end?)
11
7
 
12
8
  def initialize(predicate_builder)
13
9
  @predicate_builder = predicate_builder
@@ -16,26 +12,10 @@ module ActiveRecord
16
12
  def call(attribute, value)
17
13
  begin_bind = predicate_builder.build_bind_attribute(attribute.name, value.begin)
18
14
  end_bind = predicate_builder.build_bind_attribute(attribute.name, value.end)
19
-
20
- if begin_bind.value.infinity?
21
- if end_bind.value.infinity?
22
- attribute.not_in([])
23
- elsif value.exclude_end?
24
- attribute.lt(end_bind)
25
- else
26
- attribute.lteq(end_bind)
27
- end
28
- elsif end_bind.value.infinity?
29
- attribute.gteq(begin_bind)
30
- elsif value.exclude_end?
31
- attribute.gteq(begin_bind).and(attribute.lt(end_bind))
32
- else
33
- attribute.between(RangeWithBinds.new(begin_bind, end_bind))
34
- end
15
+ attribute.between(RangeWithBinds.new(begin_bind, end_bind, value.exclude_end?))
35
16
  end
36
17
 
37
- protected
38
-
18
+ private
39
19
  attr_reader :predicate_builder
40
20
  end
41
21
  end
@@ -27,7 +27,7 @@ module ActiveRecord
27
27
  key
28
28
  else
29
29
  key = key.to_s
30
- key.split(".".freeze).first if key.include?(".".freeze)
30
+ key.split(".").first if key.include?(".")
31
31
  end
32
32
  end.compact
33
33
  end
@@ -62,9 +62,6 @@ module ActiveRecord
62
62
  end
63
63
 
64
64
  protected
65
-
66
- attr_reader :table
67
-
68
65
  def expand_from_hash(attributes)
69
66
  return ["1=0"] if attributes.empty?
70
67
 
@@ -115,6 +112,7 @@ module ActiveRecord
115
112
  end
116
113
 
117
114
  private
115
+ attr_reader :table
118
116
 
119
117
  def associated_predicate_builder(association_name)
120
118
  self.class.new(table.associated_table(association_name))
@@ -122,11 +120,11 @@ module ActiveRecord
122
120
 
123
121
  def convert_dot_notation_to_hash(attributes)
124
122
  dot_notation = attributes.select do |k, v|
125
- k.include?(".".freeze) && !v.is_a?(Hash)
123
+ k.include?(".") && !v.is_a?(Hash)
126
124
  end
127
125
 
128
126
  dot_notation.each_key do |key|
129
- table_name, column_name = key.split(".".freeze)
127
+ table_name, column_name = key.split(".")
130
128
  value = attributes.delete(key)
131
129
  attributes[table_name] ||= {}
132
130
 
@@ -18,26 +18,29 @@ module ActiveRecord
18
18
  end
19
19
 
20
20
  def nil?
21
- unless value_before_type_cast.is_a?(StatementCache::Substitute)
22
- value_before_type_cast.nil? ||
23
- type.respond_to?(:subtype, true) && value_for_database.nil?
24
- end
21
+ !value_before_type_cast.is_a?(StatementCache::Substitute) &&
22
+ (value_before_type_cast.nil? || value_for_database.nil?)
23
+ rescue ::RangeError
25
24
  end
26
25
 
27
- def boundable?
28
- return @_boundable if defined?(@_boundable)
29
- value_for_database unless value_before_type_cast.is_a?(StatementCache::Substitute)
30
- @_boundable = true
26
+ def infinite?
27
+ infinity?(value_before_type_cast) || infinity?(value_for_database)
31
28
  rescue ::RangeError
32
- @_boundable = false
33
29
  end
34
30
 
35
- def infinity?
36
- _infinity?(value_before_type_cast) || boundable? && _infinity?(value_for_database)
31
+ def unboundable?
32
+ if defined?(@_unboundable)
33
+ @_unboundable
34
+ else
35
+ value_for_database
36
+ @_unboundable = nil
37
+ end
38
+ rescue ::RangeError
39
+ @_unboundable = type.cast(value_before_type_cast) <=> 0
37
40
  end
38
41
 
39
42
  private
40
- def _infinity?(value)
43
+ def infinity?(value)
41
44
  value.respond_to?(:infinite?) && value.infinite?
42
45
  end
43
46
  end
@@ -231,7 +231,11 @@ module ActiveRecord
231
231
  end
232
232
 
233
233
  def _select!(*fields) # :nodoc:
234
+ fields.reject!(&:blank?)
234
235
  fields.flatten!
236
+ fields.map! do |field|
237
+ klass.attribute_alias?(field) ? klass.attribute_alias(field).to_sym : field
238
+ end
235
239
  self.select_values += fields
236
240
  self
237
241
  end
@@ -895,26 +899,28 @@ module ActiveRecord
895
899
  self
896
900
  end
897
901
 
902
+ def skip_preloading! # :nodoc:
903
+ self.skip_preloading_value = true
904
+ self
905
+ end
906
+
898
907
  # Returns the Arel object associated with the relation.
899
908
  def arel(aliases = nil) # :nodoc:
900
909
  @arel ||= build_arel(aliases)
901
910
  end
902
911
 
903
- # Returns a relation value with a given name
904
- def get_value(name) # :nodoc:
905
- @values.fetch(name, DEFAULT_VALUES[name])
906
- end
907
-
908
- protected
912
+ private
913
+ # Returns a relation value with a given name
914
+ def get_value(name)
915
+ @values.fetch(name, DEFAULT_VALUES[name])
916
+ end
909
917
 
910
918
  # Sets the relation value with the given name
911
- def set_value(name, value) # :nodoc:
919
+ def set_value(name, value)
912
920
  assert_mutability!
913
921
  @values[name] = value
914
922
  end
915
923
 
916
- private
917
-
918
924
  def assert_mutability!
919
925
  raise ImmutableRelation if @loaded
920
926
  raise ImmutableRelation if defined?(@arel) && @arel
@@ -930,7 +936,7 @@ module ActiveRecord
930
936
  arel.having(having_clause.ast) unless having_clause.empty?
931
937
  if limit_value
932
938
  limit_attribute = ActiveModel::Attribute.with_cast_value(
933
- "LIMIT".freeze,
939
+ "LIMIT",
934
940
  connection.sanitize_limit(limit_value),
935
941
  Type.default_value,
936
942
  )
@@ -938,7 +944,7 @@ module ActiveRecord
938
944
  end
939
945
  if offset_value
940
946
  offset_attribute = ActiveModel::Attribute.with_cast_value(
941
- "OFFSET".freeze,
947
+ "OFFSET",
942
948
  offset_value.to_i,
943
949
  Type.default_value,
944
950
  )
@@ -1017,9 +1023,7 @@ module ActiveRecord
1017
1023
  join_list = join_nodes + convert_join_strings_to_ast(string_joins)
1018
1024
  alias_tracker = alias_tracker(join_list, aliases)
1019
1025
 
1020
- join_dependency = ActiveRecord::Associations::JoinDependency.new(
1021
- klass, table, association_joins
1022
- )
1026
+ join_dependency = construct_join_dependency(association_joins)
1023
1027
 
1024
1028
  joins = join_dependency.join_constraints(stashed_joins, join_type, alias_tracker)
1025
1029
  joins.each { |join| manager.from(join) }
@@ -1048,14 +1052,11 @@ module ActiveRecord
1048
1052
 
1049
1053
  def arel_columns(columns)
1050
1054
  columns.flat_map do |field|
1051
- case field
1052
- when Symbol
1053
- arel_column(field.to_s) do |attr_name|
1054
- connection.quote_table_name(attr_name)
1055
- end
1056
- when String
1057
- arel_column(field, &:itself)
1058
- when Proc
1055
+ if (Symbol === field || String === field) && (klass.has_attribute?(field) || klass.attribute_alias?(field)) && !from_clause.value
1056
+ arel_attribute(field)
1057
+ elsif Symbol === field
1058
+ connection.quote_table_name(field.to_s)
1059
+ elsif Proc === field
1059
1060
  field.call
1060
1061
  else
1061
1062
  field
@@ -1063,21 +1064,6 @@ module ActiveRecord
1063
1064
  end
1064
1065
  end
1065
1066
 
1066
- def arel_column(field)
1067
- field = klass.attribute_alias(field) if klass.attribute_alias?(field)
1068
- from = from_clause.name || from_clause.value
1069
-
1070
- if klass.columns_hash.key?(field) && (!from || table_name_matches?(from))
1071
- arel_attribute(field)
1072
- else
1073
- yield field
1074
- end
1075
- end
1076
-
1077
- def table_name_matches?(from)
1078
- /(?:\A|(?<!FROM)\s)(?:\b#{table.name}\b|#{connection.quote_table_name(table.name)})(?!\.)/i.match?(from.to_s)
1079
- end
1080
-
1081
1067
  def reverse_sql_order(order_query)
1082
1068
  if order_query.empty?
1083
1069
  return [arel_attribute(primary_key).desc] if primary_key
@@ -1144,9 +1130,9 @@ module ActiveRecord
1144
1130
  end
1145
1131
  order_args.flatten!
1146
1132
 
1147
- @klass.enforce_raw_sql_whitelist(
1133
+ @klass.disallow_raw_sql!(
1148
1134
  order_args.flat_map { |a| a.is_a?(Hash) ? a.keys : a },
1149
- whitelist: AttributeMethods::ClassMethods::COLUMN_NAME_ORDER_WHITELIST
1135
+ permit: AttributeMethods::ClassMethods::COLUMN_NAME_WITH_ORDER
1150
1136
  )
1151
1137
 
1152
1138
  validate_order_args(order_args)
@@ -1159,14 +1145,14 @@ module ActiveRecord
1159
1145
  order_args.map! do |arg|
1160
1146
  case arg
1161
1147
  when Symbol
1162
- order_column(arg.to_s).asc
1148
+ arel_attribute(arg).asc
1163
1149
  when Hash
1164
1150
  arg.map { |field, dir|
1165
1151
  case field
1166
1152
  when Arel::Nodes::SqlLiteral
1167
1153
  field.send(dir.downcase)
1168
1154
  else
1169
- order_column(field.to_s).send(dir.downcase)
1155
+ arel_attribute(field).send(dir.downcase)
1170
1156
  end
1171
1157
  }
1172
1158
  else
@@ -1175,16 +1161,6 @@ module ActiveRecord
1175
1161
  end.flatten!
1176
1162
  end
1177
1163
 
1178
- def order_column(field)
1179
- arel_column(field) do |attr_name|
1180
- if attr_name == "count" && !group_values.empty?
1181
- arel_attribute(attr_name)
1182
- else
1183
- Arel.sql(connection.quote_table_name(attr_name))
1184
- end
1185
- end
1186
- end
1187
-
1188
1164
  # Checks to make sure that the arguments are not blank. Note that if some
1189
1165
  # blank-like object were initially passed into the query method, then this
1190
1166
  # method will not raise an error.
@@ -1209,8 +1185,9 @@ module ActiveRecord
1209
1185
 
1210
1186
  STRUCTURAL_OR_METHODS = Relation::VALUE_METHODS - [:extending, :where, :having, :unscope, :references]
1211
1187
  def structurally_incompatible_values_for_or(other)
1188
+ values = other.values
1212
1189
  STRUCTURAL_OR_METHODS.reject do |method|
1213
- get_value(method) == other.get_value(method)
1190
+ get_value(method) == values.fetch(method, DEFAULT_VALUES[method])
1214
1191
  end
1215
1192
  end
1216
1193
 
@@ -125,6 +125,10 @@ module ActiveRecord
125
125
  raise ArgumentError, "Invalid argument for .where.not(), got nil."
126
126
  when Arel::Nodes::In
127
127
  Arel::Nodes::NotIn.new(node.left, node.right)
128
+ when Arel::Nodes::IsNotDistinctFrom
129
+ Arel::Nodes::IsDistinctFrom.new(node.left, node.right)
130
+ when Arel::Nodes::IsDistinctFrom
131
+ Arel::Nodes::IsNotDistinctFrom.new(node.left, node.right)
128
132
  when Arel::Nodes::Equality
129
133
  Arel::Nodes::NotEqual.new(node.left, node.right)
130
134
  when String
@@ -26,8 +26,7 @@ module ActiveRecord
26
26
  WhereClause.new(parts)
27
27
  end
28
28
 
29
- protected
30
-
29
+ private
31
30
  attr_reader :klass, :predicate_builder
32
31
  end
33
32
  end