activerecord 5.2.5 → 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 -748
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record.rb +2 -1
  7. data/lib/active_record/aggregations.rb +4 -2
  8. data/lib/active_record/associations.rb +16 -12
  9. data/lib/active_record/associations/association.rb +35 -19
  10. data/lib/active_record/associations/association_scope.rb +4 -6
  11. data/lib/active_record/associations/belongs_to_association.rb +36 -42
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
  13. data/lib/active_record/associations/builder/belongs_to.rb +14 -50
  14. data/lib/active_record/associations/builder/collection_association.rb +3 -3
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
  16. data/lib/active_record/associations/collection_association.rb +11 -25
  17. data/lib/active_record/associations/collection_proxy.rb +32 -6
  18. data/lib/active_record/associations/foreign_association.rb +7 -0
  19. data/lib/active_record/associations/has_many_association.rb +1 -1
  20. data/lib/active_record/associations/has_many_through_association.rb +25 -18
  21. data/lib/active_record/associations/has_one_association.rb +28 -30
  22. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  23. data/lib/active_record/associations/join_dependency.rb +15 -20
  24. data/lib/active_record/associations/join_dependency/join_association.rb +11 -26
  25. data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
  26. data/lib/active_record/associations/preloader.rb +32 -29
  27. data/lib/active_record/associations/preloader/association.rb +1 -2
  28. data/lib/active_record/associations/singular_association.rb +2 -16
  29. data/lib/active_record/attribute_assignment.rb +7 -10
  30. data/lib/active_record/attribute_methods.rb +34 -56
  31. data/lib/active_record/attribute_methods/dirty.rb +64 -26
  32. data/lib/active_record/attribute_methods/primary_key.rb +8 -7
  33. data/lib/active_record/attribute_methods/read.rb +16 -48
  34. data/lib/active_record/attribute_methods/serialization.rb +1 -1
  35. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
  36. data/lib/active_record/attribute_methods/write.rb +15 -16
  37. data/lib/active_record/autosave_association.rb +7 -21
  38. data/lib/active_record/base.rb +2 -2
  39. data/lib/active_record/callbacks.rb +3 -17
  40. data/lib/active_record/collection_cache_key.rb +1 -1
  41. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +13 -36
  42. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  43. data/lib/active_record/connection_adapters/abstract/database_statements.rb +25 -84
  44. data/lib/active_record/connection_adapters/abstract/query_cache.rb +17 -14
  45. data/lib/active_record/connection_adapters/abstract/quoting.rb +5 -11
  46. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -11
  47. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +30 -13
  48. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +0 -2
  49. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +41 -27
  50. data/lib/active_record/connection_adapters/abstract/transaction.rb +81 -52
  51. data/lib/active_record/connection_adapters/abstract_adapter.rb +95 -31
  52. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +65 -90
  53. data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
  54. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +5 -9
  55. data/lib/active_record/connection_adapters/mysql/database_statements.rb +29 -7
  56. data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
  57. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
  58. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +65 -10
  59. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -4
  60. data/lib/active_record/connection_adapters/postgresql/column.rb +1 -2
  61. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +16 -1
  62. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  63. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  64. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
  65. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
  66. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  67. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
  68. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  69. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  70. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +11 -36
  71. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +9 -2
  72. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +38 -20
  73. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -1
  74. data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -56
  75. data/lib/active_record/connection_adapters/schema_cache.rb +5 -0
  76. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +5 -5
  77. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +14 -9
  78. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +95 -62
  79. data/lib/active_record/connection_handling.rb +132 -26
  80. data/lib/active_record/core.rb +76 -43
  81. data/lib/active_record/counter_cache.rb +4 -29
  82. data/lib/active_record/database_configurations.rb +184 -0
  83. data/lib/active_record/database_configurations/database_config.rb +37 -0
  84. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  85. data/lib/active_record/database_configurations/url_config.rb +74 -0
  86. data/lib/active_record/enum.rb +22 -7
  87. data/lib/active_record/errors.rb +24 -21
  88. data/lib/active_record/explain.rb +1 -1
  89. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  90. data/lib/active_record/fixture_set/render_context.rb +17 -0
  91. data/lib/active_record/fixture_set/table_row.rb +153 -0
  92. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  93. data/lib/active_record/fixtures.rb +140 -472
  94. data/lib/active_record/gem_version.rb +4 -4
  95. data/lib/active_record/inheritance.rb +12 -2
  96. data/lib/active_record/integration.rb +56 -16
  97. data/lib/active_record/internal_metadata.rb +5 -1
  98. data/lib/active_record/locking/optimistic.rb +2 -2
  99. data/lib/active_record/locking/pessimistic.rb +3 -3
  100. data/lib/active_record/log_subscriber.rb +7 -26
  101. data/lib/active_record/migration.rb +38 -37
  102. data/lib/active_record/migration/command_recorder.rb +35 -5
  103. data/lib/active_record/migration/compatibility.rb +34 -16
  104. data/lib/active_record/model_schema.rb +30 -9
  105. data/lib/active_record/nested_attributes.rb +2 -2
  106. data/lib/active_record/no_touching.rb +7 -0
  107. data/lib/active_record/persistence.rb +18 -7
  108. data/lib/active_record/query_cache.rb +11 -4
  109. data/lib/active_record/querying.rb +19 -11
  110. data/lib/active_record/railtie.rb +71 -42
  111. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  112. data/lib/active_record/railties/controller_runtime.rb +30 -35
  113. data/lib/active_record/railties/databases.rake +94 -43
  114. data/lib/active_record/reflection.rb +60 -44
  115. data/lib/active_record/relation.rb +150 -69
  116. data/lib/active_record/relation/batches.rb +13 -10
  117. data/lib/active_record/relation/calculations.rb +38 -28
  118. data/lib/active_record/relation/delegation.rb +4 -13
  119. data/lib/active_record/relation/finder_methods.rb +12 -25
  120. data/lib/active_record/relation/merger.rb +2 -6
  121. data/lib/active_record/relation/predicate_builder.rb +4 -6
  122. data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
  123. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  124. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  125. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  126. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  127. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  128. data/lib/active_record/relation/query_attribute.rb +15 -12
  129. data/lib/active_record/relation/query_methods.rb +29 -52
  130. data/lib/active_record/relation/where_clause.rb +4 -0
  131. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  132. data/lib/active_record/result.rb +30 -11
  133. data/lib/active_record/sanitization.rb +2 -39
  134. data/lib/active_record/schema.rb +1 -10
  135. data/lib/active_record/schema_dumper.rb +12 -6
  136. data/lib/active_record/schema_migration.rb +4 -0
  137. data/lib/active_record/scoping.rb +9 -8
  138. data/lib/active_record/scoping/default.rb +10 -3
  139. data/lib/active_record/scoping/named.rb +10 -14
  140. data/lib/active_record/statement_cache.rb +32 -5
  141. data/lib/active_record/store.rb +39 -8
  142. data/lib/active_record/table_metadata.rb +1 -4
  143. data/lib/active_record/tasks/database_tasks.rb +89 -23
  144. data/lib/active_record/tasks/mysql_database_tasks.rb +2 -4
  145. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
  146. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
  147. data/lib/active_record/test_databases.rb +38 -0
  148. data/lib/active_record/test_fixtures.rb +224 -0
  149. data/lib/active_record/timestamp.rb +4 -6
  150. data/lib/active_record/transactions.rb +3 -22
  151. data/lib/active_record/translation.rb +1 -1
  152. data/lib/active_record/type.rb +3 -4
  153. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  154. data/lib/active_record/type_caster/connection.rb +1 -6
  155. data/lib/active_record/type_caster/map.rb +1 -4
  156. data/lib/active_record/validations/uniqueness.rb +13 -25
  157. data/lib/arel.rb +44 -0
  158. data/lib/arel/alias_predication.rb +9 -0
  159. data/lib/arel/attributes.rb +22 -0
  160. data/lib/arel/attributes/attribute.rb +37 -0
  161. data/lib/arel/collectors/bind.rb +24 -0
  162. data/lib/arel/collectors/composite.rb +31 -0
  163. data/lib/arel/collectors/plain_string.rb +20 -0
  164. data/lib/arel/collectors/sql_string.rb +20 -0
  165. data/lib/arel/collectors/substitute_binds.rb +28 -0
  166. data/lib/arel/crud.rb +42 -0
  167. data/lib/arel/delete_manager.rb +18 -0
  168. data/lib/arel/errors.rb +9 -0
  169. data/lib/arel/expressions.rb +29 -0
  170. data/lib/arel/factory_methods.rb +49 -0
  171. data/lib/arel/insert_manager.rb +49 -0
  172. data/lib/arel/math.rb +45 -0
  173. data/lib/arel/nodes.rb +67 -0
  174. data/lib/arel/nodes/and.rb +32 -0
  175. data/lib/arel/nodes/ascending.rb +23 -0
  176. data/lib/arel/nodes/binary.rb +52 -0
  177. data/lib/arel/nodes/bind_param.rb +36 -0
  178. data/lib/arel/nodes/case.rb +55 -0
  179. data/lib/arel/nodes/casted.rb +50 -0
  180. data/lib/arel/nodes/count.rb +12 -0
  181. data/lib/arel/nodes/delete_statement.rb +45 -0
  182. data/lib/arel/nodes/descending.rb +23 -0
  183. data/lib/arel/nodes/equality.rb +18 -0
  184. data/lib/arel/nodes/extract.rb +24 -0
  185. data/lib/arel/nodes/false.rb +16 -0
  186. data/lib/arel/nodes/full_outer_join.rb +8 -0
  187. data/lib/arel/nodes/function.rb +44 -0
  188. data/lib/arel/nodes/grouping.rb +8 -0
  189. data/lib/arel/nodes/in.rb +8 -0
  190. data/lib/arel/nodes/infix_operation.rb +80 -0
  191. data/lib/arel/nodes/inner_join.rb +8 -0
  192. data/lib/arel/nodes/insert_statement.rb +37 -0
  193. data/lib/arel/nodes/join_source.rb +20 -0
  194. data/lib/arel/nodes/matches.rb +18 -0
  195. data/lib/arel/nodes/named_function.rb +23 -0
  196. data/lib/arel/nodes/node.rb +50 -0
  197. data/lib/arel/nodes/node_expression.rb +13 -0
  198. data/lib/arel/nodes/outer_join.rb +8 -0
  199. data/lib/arel/nodes/over.rb +15 -0
  200. data/lib/arel/nodes/regexp.rb +16 -0
  201. data/lib/arel/nodes/right_outer_join.rb +8 -0
  202. data/lib/arel/nodes/select_core.rb +63 -0
  203. data/lib/arel/nodes/select_statement.rb +41 -0
  204. data/lib/arel/nodes/sql_literal.rb +16 -0
  205. data/lib/arel/nodes/string_join.rb +11 -0
  206. data/lib/arel/nodes/table_alias.rb +27 -0
  207. data/lib/arel/nodes/terminal.rb +16 -0
  208. data/lib/arel/nodes/true.rb +16 -0
  209. data/lib/arel/nodes/unary.rb +44 -0
  210. data/lib/arel/nodes/unary_operation.rb +20 -0
  211. data/lib/arel/nodes/unqualified_column.rb +22 -0
  212. data/lib/arel/nodes/update_statement.rb +41 -0
  213. data/lib/arel/nodes/values.rb +16 -0
  214. data/lib/arel/nodes/values_list.rb +24 -0
  215. data/lib/arel/nodes/window.rb +126 -0
  216. data/lib/arel/nodes/with.rb +11 -0
  217. data/lib/arel/order_predications.rb +13 -0
  218. data/lib/arel/predications.rb +257 -0
  219. data/lib/arel/select_manager.rb +271 -0
  220. data/lib/arel/table.rb +110 -0
  221. data/lib/arel/tree_manager.rb +72 -0
  222. data/lib/arel/update_manager.rb +34 -0
  223. data/lib/arel/visitors.rb +20 -0
  224. data/lib/arel/visitors/depth_first.rb +199 -0
  225. data/lib/arel/visitors/dot.rb +292 -0
  226. data/lib/arel/visitors/ibm_db.rb +21 -0
  227. data/lib/arel/visitors/informix.rb +56 -0
  228. data/lib/arel/visitors/mssql.rb +143 -0
  229. data/lib/arel/visitors/mysql.rb +83 -0
  230. data/lib/arel/visitors/oracle.rb +159 -0
  231. data/lib/arel/visitors/oracle12.rb +67 -0
  232. data/lib/arel/visitors/postgresql.rb +116 -0
  233. data/lib/arel/visitors/sqlite.rb +39 -0
  234. data/lib/arel/visitors/to_sql.rb +913 -0
  235. data/lib/arel/visitors/visitor.rb +42 -0
  236. data/lib/arel/visitors/where_sql.rb +23 -0
  237. data/lib/arel/window_predications.rb +9 -0
  238. data/lib/rails/generators/active_record/migration.rb +14 -1
  239. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  240. data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
  241. metadata +104 -26
@@ -251,25 +251,28 @@ module ActiveRecord
251
251
  end
252
252
  end
253
253
 
254
- attr = Relation::QueryAttribute.new(primary_key, primary_key_offset, klass.type_for_attribute(primary_key))
255
- batch_relation = relation.where(arel_attribute(primary_key).gt(Arel::Nodes::BindParam.new(attr)))
254
+ batch_relation = relation.where(
255
+ bind_attribute(primary_key, primary_key_offset) { |attr, bind| attr.gt(bind) }
256
+ )
256
257
  end
257
258
  end
258
259
 
259
260
  private
260
261
 
261
262
  def apply_limits(relation, start, finish)
262
- if start
263
- attr = Relation::QueryAttribute.new(primary_key, start, klass.type_for_attribute(primary_key))
264
- relation = relation.where(arel_attribute(primary_key).gteq(Arel::Nodes::BindParam.new(attr)))
265
- end
266
- if finish
267
- attr = Relation::QueryAttribute.new(primary_key, finish, klass.type_for_attribute(primary_key))
268
- relation = relation.where(arel_attribute(primary_key).lteq(Arel::Nodes::BindParam.new(attr)))
269
- end
263
+ relation = apply_start_limit(relation, start) if start
264
+ relation = apply_finish_limit(relation, finish) if finish
270
265
  relation
271
266
  end
272
267
 
268
+ def apply_start_limit(relation, start)
269
+ relation.where(bind_attribute(primary_key, start) { |attr, bind| attr.gteq(bind) })
270
+ end
271
+
272
+ def apply_finish_limit(relation, finish)
273
+ relation.where(bind_attribute(primary_key, finish) { |attr, bind| attr.lteq(bind) })
274
+ end
275
+
273
276
  def batch_order
274
277
  arel_attribute(primary_key).asc
275
278
  end
@@ -41,15 +41,13 @@ module ActiveRecord
41
41
  def count(column_name = nil)
42
42
  if block_given?
43
43
  unless column_name.nil?
44
- ActiveSupport::Deprecation.warn \
45
- "When `count' is called with a block, it ignores other arguments. " \
46
- "This behavior is now deprecated and will result in an ArgumentError in Rails 6.0."
44
+ raise ArgumentError, "Column name argument is not supported when a block is passed."
47
45
  end
48
46
 
49
- return super()
47
+ super()
48
+ else
49
+ calculate(:count, column_name)
50
50
  end
51
-
52
- calculate(:count, column_name)
53
51
  end
54
52
 
55
53
  # Calculates the average value on a given column. Returns +nil+ if there's
@@ -86,15 +84,13 @@ module ActiveRecord
86
84
  def sum(column_name = nil)
87
85
  if block_given?
88
86
  unless column_name.nil?
89
- ActiveSupport::Deprecation.warn \
90
- "When `sum' is called with a block, it ignores other arguments. " \
91
- "This behavior is now deprecated and will result in an ArgumentError in Rails 6.0."
87
+ raise ArgumentError, "Column name argument is not supported when a block is passed."
92
88
  end
93
89
 
94
- return super()
90
+ super()
91
+ else
92
+ calculate(:sum, column_name)
95
93
  end
96
-
97
- calculate(:sum, column_name)
98
94
  end
99
95
 
100
96
  # This calculates aggregate values in the given column. Methods for #count, #sum, #average,
@@ -133,12 +129,11 @@ module ActiveRecord
133
129
  relation = apply_join_dependency
134
130
 
135
131
  if operation.to_s.downcase == "count"
136
- unless distinct_value || distinct_select?(column_name || select_for_count)
137
- relation.distinct!
138
- relation.select_values = [ klass.primary_key || table[Arel.star] ]
139
- end
132
+ relation.distinct!
140
133
  # PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCT
141
- relation.order_values = []
134
+ if (column_name == :all || column_name.nil?) && select_values.empty?
135
+ relation.order_values = []
136
+ end
142
137
  end
143
138
 
144
139
  relation.calculate(operation, column_name)
@@ -191,14 +186,34 @@ module ActiveRecord
191
186
  relation = apply_join_dependency
192
187
  relation.pluck(*column_names)
193
188
  else
194
- klass.enforce_raw_sql_whitelist(column_names)
189
+ disallow_raw_sql!(column_names)
195
190
  relation = spawn
196
- relation.select_values = column_names
191
+ relation.select_values = column_names.map { |cn|
192
+ @klass.has_attribute?(cn) || @klass.attribute_alias?(cn) ? arel_attribute(cn) : cn
193
+ }
197
194
  result = skip_query_cache_if_necessary { klass.connection.select_all(relation.arel, nil) }
198
195
  result.cast_values(klass.attribute_types)
199
196
  end
200
197
  end
201
198
 
199
+ # Pick the value(s) from the named column(s) in the current relation.
200
+ # This is short-hand for <tt>relation.limit(1).pluck(*column_names).first</tt>, and is primarily useful
201
+ # when you have a relation that's already narrowed down to a single row.
202
+ #
203
+ # Just like #pluck, #pick will only load the actual value, not the entire record object, so it's also
204
+ # more efficient. The value is, again like with pluck, typecast by the column type.
205
+ #
206
+ # Person.where(id: 1).pick(:name)
207
+ # # SELECT people.name FROM people WHERE id = 1 LIMIT 1
208
+ # # => 'David'
209
+ #
210
+ # Person.where(id: 1).pick(:name, :email_address)
211
+ # # SELECT people.name, people.email_address FROM people WHERE id = 1 LIMIT 1
212
+ # # => [ 'David', 'david@loudthinking.com' ]
213
+ def pick(*column_names)
214
+ limit(1).pluck(*column_names).first
215
+ end
216
+
202
217
  # Pluck all the ID's for the relation using the table's primary key
203
218
  #
204
219
  # Person.ids # SELECT people.id FROM people
@@ -208,6 +223,7 @@ module ActiveRecord
208
223
  end
209
224
 
210
225
  private
226
+
211
227
  def has_include?(column_name)
212
228
  eager_loading? || (includes_values.present? && column_name && column_name != :all)
213
229
  end
@@ -222,12 +238,10 @@ module ActiveRecord
222
238
  if operation == "count"
223
239
  column_name ||= select_for_count
224
240
  if column_name == :all
225
- if !distinct
226
- distinct = distinct_select?(select_for_count) if group_values.empty?
227
- elsif group_values.any? || select_values.empty? && order_values.empty?
241
+ if distinct && (group_values.any? || select_values.empty? && order_values.empty?)
228
242
  column_name = primary_key
229
243
  end
230
- elsif distinct_select?(column_name)
244
+ elsif column_name.is_a?(::String) && /\bDISTINCT[\s(]/i.match?(column_name)
231
245
  distinct = nil
232
246
  end
233
247
  end
@@ -239,10 +253,6 @@ module ActiveRecord
239
253
  end
240
254
  end
241
255
 
242
- def distinct_select?(column_name)
243
- column_name.is_a?(::String) && /\bDISTINCT[\s(]/i.match?(column_name)
244
- end
245
-
246
256
  def aggregate_column(column_name)
247
257
  return column_name if Arel::Expressions === column_name
248
258
 
@@ -387,7 +397,7 @@ module ActiveRecord
387
397
  case operation
388
398
  when "count" then value.to_i
389
399
  when "sum" then type.deserialize(value || 0)
390
- when "average" then value && value.respond_to?(:to_d) ? value.to_d : value
400
+ when "average" then value&.respond_to?(:to_d) ? value.to_d : value
391
401
  else type.deserialize(value)
392
402
  end
393
403
  end
@@ -18,7 +18,7 @@ module ActiveRecord
18
18
  include ClassSpecificRelation
19
19
  }
20
20
  include_relation_methods(delegate)
21
- mangled_name = klass.name.gsub("::".freeze, "_".freeze)
21
+ mangled_name = klass.name.gsub("::", "_")
22
22
  const_set mangled_name, delegate
23
23
  private_constant mangled_name
24
24
 
@@ -33,7 +33,7 @@ module ActiveRecord
33
33
 
34
34
  protected
35
35
  def include_relation_methods(delegate)
36
- superclass.include_relation_methods(delegate) unless base_class == self
36
+ superclass.include_relation_methods(delegate) unless base_class?
37
37
  delegate.include generated_relation_methods
38
38
  end
39
39
 
@@ -54,7 +54,7 @@ module ActiveRecord
54
54
  end
55
55
  RUBY
56
56
  else
57
- generated_relation_methods.send(:define_method, method) do |*args, &block|
57
+ generated_relation_methods.define_method(method) do |*args, &block|
58
58
  scoping { klass.public_send(method, *args, &block) }
59
59
  end
60
60
  end
@@ -68,7 +68,7 @@ module ActiveRecord
68
68
  # may vary depending on the klass of a relation, so we create a subclass of Relation
69
69
  # for each different klass, and the delegations are compiled into that subclass only.
70
70
 
71
- delegate :to_xml, :encode_with, :length, :each, :uniq, :join,
71
+ delegate :to_xml, :encode_with, :length, :each, :join,
72
72
  :[], :&, :|, :+, :-, :sample, :reverse, :rotate, :compact, :in_groups, :in_groups_of,
73
73
  :to_sentence, :to_formatted_s, :as_json,
74
74
  :shuffle, :split, :slice, :index, :rindex, to: :records
@@ -112,15 +112,6 @@ module ActiveRecord
112
112
  if @klass.respond_to?(method)
113
113
  self.class.delegate_to_scoped_klass(method)
114
114
  scoping { @klass.public_send(method, *args, &block) }
115
- elsif @delegate_to_klass && @klass.respond_to?(method, true)
116
- ActiveSupport::Deprecation.warn \
117
- "Delegating missing #{method} method to #{@klass}. " \
118
- "Accessibility of private/protected class methods in :scope is deprecated and will be removed in Rails 6.0."
119
- @klass.send(method, *args, &block)
120
- elsif arel.respond_to?(method)
121
- ActiveSupport::Deprecation.warn \
122
- "Delegating #{method} to arel is deprecated and will be removed in Rails 6.0."
123
- arel.public_send(method, *args, &block)
124
115
  else
125
116
  super
126
117
  end
@@ -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
@@ -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
 
@@ -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