activerecord 6.0.0.rc1 → 6.0.3.rc1
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 +251 -3
- data/README.rdoc +1 -1
- data/lib/active_record.rb +1 -0
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +0 -1
- data/lib/active_record/association_relation.rb +10 -8
- data/lib/active_record/associations.rb +2 -2
- data/lib/active_record/associations/alias_tracker.rb +0 -1
- data/lib/active_record/associations/association.rb +5 -1
- data/lib/active_record/associations/builder/collection_association.rb +2 -2
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -3
- data/lib/active_record/associations/collection_association.rb +6 -2
- data/lib/active_record/associations/collection_proxy.rb +2 -3
- data/lib/active_record/associations/has_many_association.rb +0 -1
- data/lib/active_record/associations/join_dependency.rb +23 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +12 -3
- data/lib/active_record/associations/preloader.rb +2 -3
- data/lib/active_record/associations/preloader/association.rb +3 -1
- data/lib/active_record/attribute_assignment.rb +0 -1
- data/lib/active_record/attribute_decorators.rb +0 -2
- data/lib/active_record/attribute_methods.rb +0 -51
- data/lib/active_record/attribute_methods/before_type_cast.rb +0 -1
- data/lib/active_record/attribute_methods/dirty.rb +8 -3
- data/lib/active_record/attribute_methods/primary_key.rb +0 -2
- data/lib/active_record/attribute_methods/read.rb +0 -1
- data/lib/active_record/attribute_methods/serialization.rb +0 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +0 -2
- data/lib/active_record/attribute_methods/write.rb +0 -1
- data/lib/active_record/attributes.rb +0 -1
- data/lib/active_record/autosave_association.rb +11 -7
- data/lib/active_record/callbacks.rb +1 -2
- data/lib/active_record/coders/yaml_column.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +107 -13
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +21 -15
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +5 -5
- data/lib/active_record/connection_adapters/abstract/quoting.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +1 -2
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +27 -27
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +55 -37
- data/lib/active_record/connection_adapters/abstract/transaction.rb +14 -7
- data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -25
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +25 -32
- data/lib/active_record/connection_adapters/connection_specification.rb +3 -4
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -2
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +8 -12
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +3 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +8 -8
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -4
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +9 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +39 -2
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -29
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +17 -3
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +8 -7
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -3
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +3 -3
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +23 -8
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +17 -22
- data/lib/active_record/core.rb +8 -6
- data/lib/active_record/counter_cache.rb +4 -1
- data/lib/active_record/database_configurations.rb +60 -31
- data/lib/active_record/database_configurations/url_config.rb +0 -1
- data/lib/active_record/dynamic_matchers.rb +2 -3
- data/lib/active_record/enum.rb +9 -0
- data/lib/active_record/explain.rb +0 -1
- data/lib/active_record/fixture_set/table_row.rb +0 -1
- data/lib/active_record/fixture_set/table_rows.rb +0 -1
- data/lib/active_record/fixtures.rb +11 -9
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +0 -3
- data/lib/active_record/insert_all.rb +5 -6
- data/lib/active_record/internal_metadata.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +0 -1
- data/lib/active_record/log_subscriber.rb +1 -1
- data/lib/active_record/middleware/database_selector.rb +3 -4
- data/lib/active_record/middleware/database_selector/resolver.rb +5 -8
- data/lib/active_record/migration.rb +43 -32
- data/lib/active_record/migration/command_recorder.rb +6 -18
- data/lib/active_record/migration/compatibility.rb +3 -3
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +3 -2
- data/lib/active_record/nested_attributes.rb +0 -2
- data/lib/active_record/no_touching.rb +2 -2
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +4 -5
- data/lib/active_record/querying.rb +1 -1
- data/lib/active_record/railtie.rb +1 -2
- data/lib/active_record/railties/collection_cache_association_loading.rb +1 -1
- data/lib/active_record/railties/databases.rake +63 -23
- data/lib/active_record/reflection.rb +9 -9
- data/lib/active_record/relation.rb +13 -1
- data/lib/active_record/relation/batches.rb +0 -1
- data/lib/active_record/relation/calculations.rb +3 -5
- data/lib/active_record/relation/delegation.rb +7 -6
- data/lib/active_record/relation/finder_methods.rb +14 -4
- data/lib/active_record/relation/from_clause.rb +4 -0
- data/lib/active_record/relation/merger.rb +6 -3
- data/lib/active_record/relation/predicate_builder.rb +1 -5
- data/lib/active_record/relation/query_methods.rb +94 -55
- data/lib/active_record/relation/spawn_methods.rb +0 -1
- data/lib/active_record/relation/where_clause.rb +0 -1
- data/lib/active_record/result.rb +0 -1
- data/lib/active_record/sanitization.rb +30 -2
- data/lib/active_record/schema.rb +1 -1
- data/lib/active_record/schema_dumper.rb +5 -1
- data/lib/active_record/schema_migration.rb +1 -1
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/scoping/default.rb +0 -1
- data/lib/active_record/scoping/named.rb +3 -3
- data/lib/active_record/store.rb +1 -1
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +21 -10
- data/lib/active_record/tasks/database_tasks.rb +76 -8
- data/lib/active_record/tasks/mysql_database_tasks.rb +3 -2
- data/lib/active_record/tasks/postgresql_database_tasks.rb +0 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +0 -1
- data/lib/active_record/test_databases.rb +1 -16
- data/lib/active_record/test_fixtures.rb +2 -1
- data/lib/active_record/timestamp.rb +26 -17
- data/lib/active_record/touch_later.rb +3 -2
- data/lib/active_record/transactions.rb +18 -19
- data/lib/active_record/type.rb +0 -1
- data/lib/active_record/type/adapter_specific_registry.rb +2 -5
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +0 -1
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type_caster/connection.rb +16 -10
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/arel.rb +17 -6
- data/lib/arel/predications.rb +5 -6
- data/lib/arel/visitors/depth_first.rb +1 -2
- data/lib/arel/visitors/dot.rb +0 -1
- data/lib/arel/visitors/mssql.rb +0 -1
- data/lib/arel/visitors/oracle.rb +1 -2
- data/lib/arel/visitors/oracle12.rb +0 -1
- data/lib/arel/visitors/postgresql.rb +0 -1
- data/lib/arel/visitors/sqlite.rb +0 -1
- data/lib/arel/visitors/to_sql.rb +23 -27
- data/lib/arel/visitors/visitor.rb +9 -6
- data/lib/arel/visitors/where_sql.rb +0 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration.rb +0 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +0 -1
- metadata +13 -9
@@ -36,7 +36,7 @@ module ActiveRecord
|
|
36
36
|
#
|
37
37
|
# # A simple SQL query spanning multiple tables
|
38
38
|
# Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
|
39
|
-
# # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "
|
39
|
+
# # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "author"=>"Quentin"}>, ...]
|
40
40
|
#
|
41
41
|
# You can use the same string replacement techniques as you can with <tt>ActiveRecord::QueryMethods#where</tt>:
|
42
42
|
#
|
@@ -114,7 +114,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
114
114
|
|
115
115
|
config.active_record.cache_versioning = false
|
116
116
|
|
117
|
-
end_error
|
117
|
+
end_error
|
118
118
|
end
|
119
119
|
end
|
120
120
|
end
|
@@ -134,7 +134,6 @@ end_error
|
|
134
134
|
|
135
135
|
cache = YAML.load(File.read(filename))
|
136
136
|
if cache.version == current_version
|
137
|
-
connection.schema_cache = cache
|
138
137
|
connection_pool.schema_cache = cache.dup
|
139
138
|
else
|
140
139
|
warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require "active_record"
|
4
4
|
|
5
|
+
databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
|
6
|
+
|
5
7
|
db_namespace = namespace :db do
|
6
8
|
desc "Set the environment value for the database"
|
7
9
|
task "environment:set" => :load_config do
|
@@ -23,7 +25,7 @@ db_namespace = namespace :db do
|
|
23
25
|
ActiveRecord::Tasks::DatabaseTasks.create_all
|
24
26
|
end
|
25
27
|
|
26
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
28
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
27
29
|
desc "Create #{spec_name} database for current environment"
|
28
30
|
task spec_name => :load_config do
|
29
31
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
@@ -42,7 +44,7 @@ db_namespace = namespace :db do
|
|
42
44
|
ActiveRecord::Tasks::DatabaseTasks.drop_all
|
43
45
|
end
|
44
46
|
|
45
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
47
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
46
48
|
desc "Drop #{spec_name} database for current environment"
|
47
49
|
task spec_name => [:load_config, :check_protected_environments] do
|
48
50
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
@@ -78,11 +80,14 @@ db_namespace = namespace :db do
|
|
78
80
|
|
79
81
|
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
|
80
82
|
task migrate: :load_config do
|
83
|
+
original_config = ActiveRecord::Base.connection_config
|
81
84
|
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
82
85
|
ActiveRecord::Base.establish_connection(db_config.config)
|
83
86
|
ActiveRecord::Tasks::DatabaseTasks.migrate
|
84
87
|
end
|
85
88
|
db_namespace["_dump"].invoke
|
89
|
+
ensure
|
90
|
+
ActiveRecord::Base.establish_connection(original_config)
|
86
91
|
end
|
87
92
|
|
88
93
|
# IMPORTANT: This task won't dump the schema if ActiveRecord::Base.dump_schema_after_migration is set to false
|
@@ -101,7 +106,7 @@ db_namespace = namespace :db do
|
|
101
106
|
end
|
102
107
|
|
103
108
|
namespace :migrate do
|
104
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
109
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
105
110
|
desc "Migrate #{spec_name} database for current environment"
|
106
111
|
task spec_name => :load_config do
|
107
112
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
@@ -142,7 +147,7 @@ db_namespace = namespace :db do
|
|
142
147
|
end
|
143
148
|
|
144
149
|
namespace :up do
|
145
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
150
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
146
151
|
task spec_name => :load_config do
|
147
152
|
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
148
153
|
|
@@ -176,7 +181,7 @@ db_namespace = namespace :db do
|
|
176
181
|
end
|
177
182
|
|
178
183
|
namespace :down do
|
179
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
184
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
180
185
|
task spec_name => :load_config do
|
181
186
|
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
182
187
|
|
@@ -203,7 +208,7 @@ db_namespace = namespace :db do
|
|
203
208
|
end
|
204
209
|
|
205
210
|
namespace :status do
|
206
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
211
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
207
212
|
desc "Display status of migrations for #{spec_name} database"
|
208
213
|
task spec_name => :load_config do
|
209
214
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
@@ -250,7 +255,11 @@ db_namespace = namespace :db do
|
|
250
255
|
|
251
256
|
# desc "Raises an error if there are pending migrations"
|
252
257
|
task abort_if_pending_migrations: :load_config do
|
253
|
-
pending_migrations = ActiveRecord::Base.
|
258
|
+
pending_migrations = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).flat_map do |db_config|
|
259
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
260
|
+
|
261
|
+
ActiveRecord::Base.connection.migration_context.open.pending_migrations
|
262
|
+
end
|
254
263
|
|
255
264
|
if pending_migrations.any?
|
256
265
|
puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
|
@@ -259,6 +268,28 @@ db_namespace = namespace :db do
|
|
259
268
|
end
|
260
269
|
abort %{Run `rails db:migrate` to update your database then try again.}
|
261
270
|
end
|
271
|
+
ensure
|
272
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
|
273
|
+
end
|
274
|
+
|
275
|
+
namespace :abort_if_pending_migrations do
|
276
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
277
|
+
# desc "Raises an error if there are pending migrations for #{spec_name} database"
|
278
|
+
task spec_name => :load_config do
|
279
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
280
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
281
|
+
|
282
|
+
pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
|
283
|
+
|
284
|
+
if pending_migrations.any?
|
285
|
+
puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
|
286
|
+
pending_migrations.each do |pending_migration|
|
287
|
+
puts " %4d %s" % [pending_migration.version, pending_migration.name]
|
288
|
+
end
|
289
|
+
abort %{Run `rails db:migrate:#{spec_name}` to update your database then try again.}
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
262
293
|
end
|
263
294
|
|
264
295
|
desc "Creates the database, loads the schema, and initializes with the seed data (use db:reset to also drop the database first)"
|
@@ -266,12 +297,32 @@ db_namespace = namespace :db do
|
|
266
297
|
|
267
298
|
desc "Runs setup if database does not exist, or runs migrations if it does"
|
268
299
|
task prepare: :load_config do
|
300
|
+
seed = false
|
301
|
+
|
269
302
|
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
270
303
|
ActiveRecord::Base.establish_connection(db_config.config)
|
271
|
-
|
304
|
+
|
305
|
+
# Skipped when no database
|
306
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate
|
307
|
+
if ActiveRecord::Base.dump_schema_after_migration
|
308
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, ActiveRecord::Base.schema_format, db_config.spec_name)
|
309
|
+
end
|
310
|
+
|
272
311
|
rescue ActiveRecord::NoDatabaseError
|
273
|
-
|
312
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current(db_config.env_name, db_config.spec_name)
|
313
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(
|
314
|
+
db_config.config,
|
315
|
+
ActiveRecord::Base.schema_format,
|
316
|
+
nil,
|
317
|
+
db_config.env_name,
|
318
|
+
db_config.spec_name
|
319
|
+
)
|
320
|
+
|
321
|
+
seed = true
|
274
322
|
end
|
323
|
+
|
324
|
+
ActiveRecord::Base.establish_connection
|
325
|
+
ActiveRecord::Tasks::DatabaseTasks.load_seed if seed
|
275
326
|
end
|
276
327
|
|
277
328
|
desc "Loads the seed data from db/seeds.rb"
|
@@ -336,13 +387,9 @@ db_namespace = namespace :db do
|
|
336
387
|
namespace :schema do
|
337
388
|
desc "Creates a db/schema.rb file that is portable against any DB supported by Active Record"
|
338
389
|
task dump: :load_config do
|
339
|
-
require "active_record/schema_dumper"
|
340
390
|
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
341
|
-
|
342
|
-
|
343
|
-
ActiveRecord::Base.establish_connection(db_config.config)
|
344
|
-
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
345
|
-
end
|
391
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
392
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, :ruby, db_config.spec_name)
|
346
393
|
end
|
347
394
|
|
348
395
|
db_namespace["schema:dump"].reenable
|
@@ -385,14 +432,7 @@ db_namespace = namespace :db do
|
|
385
432
|
task dump: :load_config do
|
386
433
|
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
387
434
|
ActiveRecord::Base.establish_connection(db_config.config)
|
388
|
-
|
389
|
-
ActiveRecord::Tasks::DatabaseTasks.structure_dump(db_config.config, filename)
|
390
|
-
if ActiveRecord::SchemaMigration.table_exists?
|
391
|
-
File.open(filename, "a") do |f|
|
392
|
-
f.puts ActiveRecord::Base.connection.dump_schema_information
|
393
|
-
f.print "\n"
|
394
|
-
end
|
395
|
-
end
|
435
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, :sql, db_config.spec_name)
|
396
436
|
end
|
397
437
|
|
398
438
|
db_namespace["structure:dump"].reenable
|
@@ -183,20 +183,22 @@ module ActiveRecord
|
|
183
183
|
scope_chain_items = join_scopes(table, predicate_builder)
|
184
184
|
klass_scope = klass_join_scope(table, predicate_builder)
|
185
185
|
|
186
|
+
if type
|
187
|
+
klass_scope.where!(type => foreign_klass.polymorphic_name)
|
188
|
+
end
|
189
|
+
|
190
|
+
scope_chain_items.inject(klass_scope, &:merge!)
|
191
|
+
|
186
192
|
key = join_keys.key
|
187
193
|
foreign_key = join_keys.foreign_key
|
188
194
|
|
189
195
|
klass_scope.where!(table[key].eq(foreign_table[foreign_key]))
|
190
196
|
|
191
|
-
if type
|
192
|
-
klass_scope.where!(type => foreign_klass.polymorphic_name)
|
193
|
-
end
|
194
|
-
|
195
197
|
if klass.finder_needs_type_condition?
|
196
198
|
klass_scope.where!(klass.send(:type_condition, table))
|
197
199
|
end
|
198
200
|
|
199
|
-
|
201
|
+
klass_scope
|
200
202
|
end
|
201
203
|
|
202
204
|
def join_scopes(table, predicate_builder) # :nodoc:
|
@@ -477,7 +479,7 @@ module ActiveRecord
|
|
477
479
|
def check_preloadable!
|
478
480
|
return unless scope
|
479
481
|
|
480
|
-
|
482
|
+
unless scope.arity == 0
|
481
483
|
raise ArgumentError, <<-MSG.squish
|
482
484
|
The association scope '#{name}' is instance dependent (the scope
|
483
485
|
block takes an argument). Preloading instance dependent scopes is
|
@@ -590,7 +592,6 @@ module ActiveRecord
|
|
590
592
|
end
|
591
593
|
|
592
594
|
private
|
593
|
-
|
594
595
|
def calculate_constructable(macro, options)
|
595
596
|
true
|
596
597
|
end
|
@@ -620,7 +621,7 @@ module ActiveRecord
|
|
620
621
|
end
|
621
622
|
|
622
623
|
if valid_inverse_reflection?(reflection)
|
623
|
-
|
624
|
+
inverse_name
|
624
625
|
end
|
625
626
|
end
|
626
627
|
end
|
@@ -704,7 +705,6 @@ module ActiveRecord
|
|
704
705
|
end
|
705
706
|
|
706
707
|
private
|
707
|
-
|
708
708
|
def calculate_constructable(macro, options)
|
709
709
|
!options[:through]
|
710
710
|
end
|
@@ -385,6 +385,15 @@ module ActiveRecord
|
|
385
385
|
end
|
386
386
|
private :compute_cache_version
|
387
387
|
|
388
|
+
# Returns a cache key along with the version.
|
389
|
+
def cache_key_with_version
|
390
|
+
if version = cache_version
|
391
|
+
"#{cache_key}-#{version}"
|
392
|
+
else
|
393
|
+
cache_key
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
388
397
|
# Scope all queries to the current scope.
|
389
398
|
#
|
390
399
|
# Comment.where(post_id: 1).scoping do
|
@@ -479,7 +488,9 @@ module ActiveRecord
|
|
479
488
|
|
480
489
|
if touch
|
481
490
|
names = touch if touch != true
|
482
|
-
|
491
|
+
names = Array.wrap(names)
|
492
|
+
options = names.extract_options!
|
493
|
+
touch_updates = klass.touch_attributes_with_time(*names, **options)
|
483
494
|
updates.merge!(touch_updates) unless touch_updates.empty?
|
484
495
|
end
|
485
496
|
|
@@ -629,6 +640,7 @@ module ActiveRecord
|
|
629
640
|
@to_sql = @arel = @loaded = @should_eager_load = nil
|
630
641
|
@records = [].freeze
|
631
642
|
@offsets = {}
|
643
|
+
@take = nil
|
632
644
|
self
|
633
645
|
end
|
634
646
|
|
@@ -172,7 +172,7 @@ module ActiveRecord
|
|
172
172
|
# # SELECT people.id FROM people WHERE people.age = 21 LIMIT 5
|
173
173
|
# # => [2, 3]
|
174
174
|
#
|
175
|
-
# Person.pluck('DATEDIFF(updated_at, created_at)')
|
175
|
+
# Person.pluck(Arel.sql('DATEDIFF(updated_at, created_at)'))
|
176
176
|
# # SELECT DATEDIFF(updated_at, created_at) FROM people
|
177
177
|
# # => ['0', '27761', '173']
|
178
178
|
#
|
@@ -321,7 +321,7 @@ module ActiveRecord
|
|
321
321
|
}
|
322
322
|
group_columns = group_aliases.zip(group_fields)
|
323
323
|
|
324
|
-
aggregate_alias = column_alias_for("#{operation}
|
324
|
+
aggregate_alias = column_alias_for("#{operation} #{column_name.to_s.downcase}")
|
325
325
|
|
326
326
|
select_values = [
|
327
327
|
operation_over_aggregate_column(
|
@@ -340,7 +340,7 @@ module ActiveRecord
|
|
340
340
|
}
|
341
341
|
|
342
342
|
relation = except(:group).distinct!(false)
|
343
|
-
relation.group_values =
|
343
|
+
relation.group_values = group_fields
|
344
344
|
relation.select_values = select_values
|
345
345
|
|
346
346
|
calculated_data = skip_query_cache_if_necessary { @klass.connection.select_all(relation.arel, nil) }
|
@@ -374,8 +374,6 @@ module ActiveRecord
|
|
374
374
|
# column_alias_for("count(distinct users.id)") # => "count_distinct_users_id"
|
375
375
|
# column_alias_for("count(*)") # => "count_all"
|
376
376
|
def column_alias_for(field)
|
377
|
-
return field if field.match?(/\A\w{,#{connection.table_alias_length}}\z/)
|
378
|
-
|
379
377
|
column_alias = +field
|
380
378
|
column_alias.gsub!(/\*/, "all")
|
381
379
|
column_alias.gsub!(/\W+/, " ")
|
@@ -60,15 +60,17 @@ module ActiveRecord
|
|
60
60
|
return if method_defined?(method)
|
61
61
|
|
62
62
|
if /\A[a-zA-Z_]\w*[!?]?\z/.match?(method)
|
63
|
+
definition = RUBY_VERSION >= "2.7" ? "..." : "*args, &block"
|
63
64
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
64
|
-
def #{method}(
|
65
|
-
scoping { klass.#{method}(
|
65
|
+
def #{method}(#{definition})
|
66
|
+
scoping { klass.#{method}(#{definition}) }
|
66
67
|
end
|
67
68
|
RUBY
|
68
69
|
else
|
69
70
|
define_method(method) do |*args, &block|
|
70
71
|
scoping { klass.public_send(method, *args, &block) }
|
71
72
|
end
|
73
|
+
ruby2_keywords(method) if respond_to?(:ruby2_keywords, true)
|
72
74
|
end
|
73
75
|
end
|
74
76
|
end
|
@@ -99,7 +101,6 @@ module ActiveRecord
|
|
99
101
|
end
|
100
102
|
|
101
103
|
private
|
102
|
-
|
103
104
|
def method_missing(method, *args, &block)
|
104
105
|
if @klass.respond_to?(method)
|
105
106
|
@klass.generate_relation_method(method)
|
@@ -108,15 +109,15 @@ module ActiveRecord
|
|
108
109
|
super
|
109
110
|
end
|
110
111
|
end
|
112
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
111
113
|
end
|
112
114
|
|
113
115
|
module ClassMethods # :nodoc:
|
114
|
-
def create(klass, *args)
|
115
|
-
relation_class_for(klass).new(klass, *args)
|
116
|
+
def create(klass, *args, **kwargs)
|
117
|
+
relation_class_for(klass).new(klass, *args, **kwargs)
|
116
118
|
end
|
117
119
|
|
118
120
|
private
|
119
|
-
|
120
121
|
def relation_class_for(klass)
|
121
122
|
klass.relation_delegate_class(self)
|
122
123
|
end
|
@@ -346,7 +346,6 @@ module ActiveRecord
|
|
346
346
|
end
|
347
347
|
|
348
348
|
private
|
349
|
-
|
350
349
|
def offset_index
|
351
350
|
offset_value || 0
|
352
351
|
end
|
@@ -355,7 +354,7 @@ module ActiveRecord
|
|
355
354
|
conditions = sanitize_forbidden_attributes(conditions)
|
356
355
|
|
357
356
|
if distinct_value && offset_value
|
358
|
-
relation = limit(1)
|
357
|
+
relation = except(:order).limit!(1)
|
359
358
|
else
|
360
359
|
relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
|
361
360
|
end
|
@@ -371,10 +370,21 @@ module ActiveRecord
|
|
371
370
|
end
|
372
371
|
|
373
372
|
def apply_join_dependency(eager_loading: group_values.empty?)
|
374
|
-
join_dependency = construct_join_dependency(
|
373
|
+
join_dependency = construct_join_dependency(
|
374
|
+
eager_load_values + includes_values, Arel::Nodes::OuterJoin
|
375
|
+
)
|
375
376
|
relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
|
376
377
|
|
377
|
-
if eager_loading && !
|
378
|
+
if eager_loading && !(
|
379
|
+
using_limitable_reflections?(join_dependency.reflections) &&
|
380
|
+
using_limitable_reflections?(
|
381
|
+
construct_join_dependency(
|
382
|
+
select_association_list(joins_values).concat(
|
383
|
+
select_association_list(left_outer_joins_values)
|
384
|
+
), nil
|
385
|
+
).reflections
|
386
|
+
)
|
387
|
+
)
|
378
388
|
if has_limit_or_offset?
|
379
389
|
limited_ids = limited_ids_for(relation)
|
380
390
|
limited_ids.empty? ? relation.none! : relation.where!(primary_key => limited_ids)
|