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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +299 -748
- data/MIT-LICENSE +3 -1
- data/README.rdoc +1 -1
- data/examples/performance.rb +1 -1
- data/lib/active_record.rb +2 -1
- data/lib/active_record/aggregations.rb +4 -2
- data/lib/active_record/associations.rb +16 -12
- data/lib/active_record/associations/association.rb +35 -19
- data/lib/active_record/associations/association_scope.rb +4 -6
- data/lib/active_record/associations/belongs_to_association.rb +36 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
- data/lib/active_record/associations/builder/belongs_to.rb +14 -50
- data/lib/active_record/associations/builder/collection_association.rb +3 -3
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
- data/lib/active_record/associations/collection_association.rb +11 -25
- data/lib/active_record/associations/collection_proxy.rb +32 -6
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +25 -18
- data/lib/active_record/associations/has_one_association.rb +28 -30
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency.rb +15 -20
- data/lib/active_record/associations/join_dependency/join_association.rb +11 -26
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/preloader.rb +32 -29
- data/lib/active_record/associations/preloader/association.rb +1 -2
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/attribute_assignment.rb +7 -10
- data/lib/active_record/attribute_methods.rb +34 -56
- data/lib/active_record/attribute_methods/dirty.rb +64 -26
- data/lib/active_record/attribute_methods/primary_key.rb +8 -7
- data/lib/active_record/attribute_methods/read.rb +16 -48
- data/lib/active_record/attribute_methods/serialization.rb +1 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
- data/lib/active_record/attribute_methods/write.rb +15 -16
- data/lib/active_record/autosave_association.rb +7 -21
- data/lib/active_record/base.rb +2 -2
- data/lib/active_record/callbacks.rb +3 -17
- data/lib/active_record/collection_cache_key.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +13 -36
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +25 -84
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +17 -14
- data/lib/active_record/connection_adapters/abstract/quoting.rb +5 -11
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -11
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +30 -13
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +0 -2
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +41 -27
- data/lib/active_record/connection_adapters/abstract/transaction.rb +81 -52
- data/lib/active_record/connection_adapters/abstract_adapter.rb +95 -31
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +65 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +5 -9
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +29 -7
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +65 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -4
- data/lib/active_record/connection_adapters/postgresql/column.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +16 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +11 -36
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +9 -2
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +38 -20
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -56
- data/lib/active_record/connection_adapters/schema_cache.rb +5 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +5 -5
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +14 -9
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +95 -62
- data/lib/active_record/connection_handling.rb +132 -26
- data/lib/active_record/core.rb +76 -43
- data/lib/active_record/counter_cache.rb +4 -29
- data/lib/active_record/database_configurations.rb +184 -0
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +74 -0
- data/lib/active_record/enum.rb +22 -7
- data/lib/active_record/errors.rb +24 -21
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +140 -472
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +12 -2
- data/lib/active_record/integration.rb +56 -16
- data/lib/active_record/internal_metadata.rb +5 -1
- data/lib/active_record/locking/optimistic.rb +2 -2
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +7 -26
- data/lib/active_record/migration.rb +38 -37
- data/lib/active_record/migration/command_recorder.rb +35 -5
- data/lib/active_record/migration/compatibility.rb +34 -16
- data/lib/active_record/model_schema.rb +30 -9
- data/lib/active_record/nested_attributes.rb +2 -2
- data/lib/active_record/no_touching.rb +7 -0
- data/lib/active_record/persistence.rb +18 -7
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +19 -11
- data/lib/active_record/railtie.rb +71 -42
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +94 -43
- data/lib/active_record/reflection.rb +60 -44
- data/lib/active_record/relation.rb +150 -69
- data/lib/active_record/relation/batches.rb +13 -10
- data/lib/active_record/relation/calculations.rb +38 -28
- data/lib/active_record/relation/delegation.rb +4 -13
- data/lib/active_record/relation/finder_methods.rb +12 -25
- data/lib/active_record/relation/merger.rb +2 -6
- data/lib/active_record/relation/predicate_builder.rb +4 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/query_attribute.rb +15 -12
- data/lib/active_record/relation/query_methods.rb +29 -52
- data/lib/active_record/relation/where_clause.rb +4 -0
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/result.rb +30 -11
- data/lib/active_record/sanitization.rb +2 -39
- data/lib/active_record/schema.rb +1 -10
- data/lib/active_record/schema_dumper.rb +12 -6
- data/lib/active_record/schema_migration.rb +4 -0
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/scoping/default.rb +10 -3
- data/lib/active_record/scoping/named.rb +10 -14
- data/lib/active_record/statement_cache.rb +32 -5
- data/lib/active_record/store.rb +39 -8
- data/lib/active_record/table_metadata.rb +1 -4
- data/lib/active_record/tasks/database_tasks.rb +89 -23
- data/lib/active_record/tasks/mysql_database_tasks.rb +2 -4
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
- data/lib/active_record/test_databases.rb +38 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +4 -6
- data/lib/active_record/transactions.rb +3 -22
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type.rb +3 -4
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type_caster/connection.rb +1 -6
- data/lib/active_record/type_caster/map.rb +1 -4
- data/lib/active_record/validations/uniqueness.rb +13 -25
- data/lib/arel.rb +44 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes.rb +67 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +63 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values.rb +16 -0
- data/lib/arel/nodes/values_list.rb +24 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +257 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/visitors/depth_first.rb +199 -0
- data/lib/arel/visitors/dot.rb +292 -0
- data/lib/arel/visitors/ibm_db.rb +21 -0
- data/lib/arel/visitors/informix.rb +56 -0
- data/lib/arel/visitors/mssql.rb +143 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +159 -0
- data/lib/arel/visitors/oracle12.rb +67 -0
- data/lib/arel/visitors/postgresql.rb +116 -0
- data/lib/arel/visitors/sqlite.rb +39 -0
- data/lib/arel/visitors/to_sql.rb +913 -0
- data/lib/arel/visitors/visitor.rb +42 -0
- data/lib/arel/visitors/where_sql.rb +23 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/rails/generators/active_record/migration.rb +14 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
- metadata +104 -26
@@ -251,25 +251,28 @@ module ActiveRecord
|
|
251
251
|
end
|
252
252
|
end
|
253
253
|
|
254
|
-
|
255
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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("::"
|
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
|
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.
|
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, :
|
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.
|
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}"
|
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}': "
|
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
|
-
|
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,
|
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.
|
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
|
-
|
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
|
-
|
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("."
|
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?("."
|
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("."
|
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
|
15
|
-
ranges
|
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
|
-
|
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
|
-
|
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
|