activerecord 5.2.8.1 → 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 -816
- data/MIT-LICENSE +3 -1
- data/README.rdoc +1 -1
- data/examples/performance.rb +1 -1
- data/lib/active_record/aggregations.rb +4 -2
- 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/join_association.rb +11 -26
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/join_dependency.rb +15 -20
- data/lib/active_record/associations/preloader/association.rb +1 -2
- data/lib/active_record/associations/preloader.rb +32 -29
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/associations.rb +16 -12
- data/lib/active_record/attribute_assignment.rb +7 -10
- 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/attribute_methods.rb +34 -56
- 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/coders/yaml_column.rb +1 -13
- 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 +75 -52
- data/lib/active_record/counter_cache.rb +4 -29
- 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/database_configurations.rb +184 -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/command_recorder.rb +35 -5
- data/lib/active_record/migration/compatibility.rb +34 -16
- data/lib/active_record/migration.rb +38 -37
- 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 -60
- 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/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/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/predicate_builder.rb +4 -6
- 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/relation.rb +150 -69
- 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/default.rb +10 -3
- data/lib/active_record/scoping/named.rb +10 -14
- data/lib/active_record/scoping.rb +9 -8
- 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/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type.rb +3 -4
- 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/active_record.rb +2 -1
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -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/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/nodes.rb +67 -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/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/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +44 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/migration.rb +14 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
- metadata +107 -29
@@ -22,6 +22,14 @@ db_namespace = namespace :db do
|
|
22
22
|
task all: :load_config do
|
23
23
|
ActiveRecord::Tasks::DatabaseTasks.create_all
|
24
24
|
end
|
25
|
+
|
26
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
27
|
+
desc "Create #{spec_name} database for current environment"
|
28
|
+
task spec_name => :load_config do
|
29
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
30
|
+
ActiveRecord::Tasks::DatabaseTasks.create(db_config.config)
|
31
|
+
end
|
32
|
+
end
|
25
33
|
end
|
26
34
|
|
27
35
|
desc "Creates the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to creating the development and test databases."
|
@@ -33,6 +41,14 @@ db_namespace = namespace :db do
|
|
33
41
|
task all: [:load_config, :check_protected_environments] do
|
34
42
|
ActiveRecord::Tasks::DatabaseTasks.drop_all
|
35
43
|
end
|
44
|
+
|
45
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
46
|
+
desc "Drop #{spec_name} database for current environment"
|
47
|
+
task spec_name => [:load_config, :check_protected_environments] do
|
48
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
49
|
+
ActiveRecord::Tasks::DatabaseTasks.drop(db_config.config)
|
50
|
+
end
|
51
|
+
end
|
36
52
|
end
|
37
53
|
|
38
54
|
desc "Drops the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to dropping the development and test databases."
|
@@ -57,7 +73,10 @@ db_namespace = namespace :db do
|
|
57
73
|
|
58
74
|
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
|
59
75
|
task migrate: :load_config do
|
60
|
-
ActiveRecord::
|
76
|
+
ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
|
77
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
78
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate
|
79
|
+
end
|
61
80
|
db_namespace["_dump"].invoke
|
62
81
|
end
|
63
82
|
|
@@ -77,6 +96,15 @@ db_namespace = namespace :db do
|
|
77
96
|
end
|
78
97
|
|
79
98
|
namespace :migrate do
|
99
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
100
|
+
desc "Migrate #{spec_name} database for current environment"
|
101
|
+
task spec_name => :load_config do
|
102
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
103
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
104
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
80
108
|
# desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
|
81
109
|
task redo: :load_config do
|
82
110
|
raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
|
@@ -121,18 +149,21 @@ db_namespace = namespace :db do
|
|
121
149
|
|
122
150
|
desc "Display status of migrations"
|
123
151
|
task status: :load_config do
|
124
|
-
|
125
|
-
|
152
|
+
ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
|
153
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
154
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate_status
|
126
155
|
end
|
156
|
+
end
|
127
157
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
158
|
+
namespace :status do
|
159
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
160
|
+
desc "Display status of migrations for #{spec_name} database"
|
161
|
+
task spec_name => :load_config do
|
162
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
163
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
164
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate_status
|
165
|
+
end
|
134
166
|
end
|
135
|
-
puts
|
136
167
|
end
|
137
168
|
end
|
138
169
|
|
@@ -160,11 +191,9 @@ db_namespace = namespace :db do
|
|
160
191
|
|
161
192
|
# desc "Retrieves the collation for the current environment's database"
|
162
193
|
task collation: :load_config do
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
$stderr.puts "Sorry, your database adapter is not supported yet. Feel free to submit a patch."
|
167
|
-
end
|
194
|
+
puts ActiveRecord::Tasks::DatabaseTasks.collation_current
|
195
|
+
rescue NoMethodError
|
196
|
+
$stderr.puts "Sorry, your database adapter is not supported yet. Feel free to submit a patch."
|
168
197
|
end
|
169
198
|
|
170
199
|
desc "Retrieves the current schema version number"
|
@@ -189,7 +218,7 @@ db_namespace = namespace :db do
|
|
189
218
|
task setup: ["db:schema:load_if_ruby", "db:structure:load_if_sql", :seed]
|
190
219
|
|
191
220
|
desc "Loads the seed data from db/seeds.rb"
|
192
|
-
task :
|
221
|
+
task seed: :load_config do
|
193
222
|
db_namespace["abort_if_pending_migrations"].invoke
|
194
223
|
ActiveRecord::Tasks::DatabaseTasks.load_seed
|
195
224
|
end
|
@@ -246,10 +275,14 @@ db_namespace = namespace :db do
|
|
246
275
|
desc "Creates a db/schema.rb file that is portable against any DB supported by Active Record"
|
247
276
|
task dump: :load_config do
|
248
277
|
require "active_record/schema_dumper"
|
249
|
-
|
250
|
-
|
251
|
-
|
278
|
+
ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
|
279
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :ruby)
|
280
|
+
File.open(filename, "w:utf-8") do |file|
|
281
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
282
|
+
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
283
|
+
end
|
252
284
|
end
|
285
|
+
|
253
286
|
db_namespace["schema:dump"].reenable
|
254
287
|
end
|
255
288
|
|
@@ -265,33 +298,41 @@ db_namespace = namespace :db do
|
|
265
298
|
namespace :cache do
|
266
299
|
desc "Creates a db/schema_cache.yml file."
|
267
300
|
task dump: :load_config do
|
268
|
-
|
269
|
-
|
270
|
-
|
301
|
+
ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
|
302
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
303
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.spec_name)
|
304
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(
|
305
|
+
ActiveRecord::Base.connection,
|
306
|
+
filename,
|
307
|
+
)
|
308
|
+
end
|
271
309
|
end
|
272
310
|
|
273
311
|
desc "Clears a db/schema_cache.yml file."
|
274
312
|
task clear: :load_config do
|
275
|
-
|
276
|
-
|
313
|
+
ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
|
314
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.spec_name)
|
315
|
+
rm_f filename, verbose: false
|
316
|
+
end
|
277
317
|
end
|
278
318
|
end
|
279
|
-
|
280
319
|
end
|
281
320
|
|
282
321
|
namespace :structure do
|
283
322
|
desc "Dumps the database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
|
284
323
|
task dump: :load_config do
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
324
|
+
ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
|
325
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
326
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :sql)
|
327
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_dump(db_config.config, filename)
|
328
|
+
if ActiveRecord::SchemaMigration.table_exists?
|
329
|
+
File.open(filename, "a") do |f|
|
330
|
+
f.puts ActiveRecord::Base.connection.dump_schema_information
|
331
|
+
f.print "\n"
|
332
|
+
end
|
293
333
|
end
|
294
334
|
end
|
335
|
+
|
295
336
|
db_namespace["structure:dump"].reenable
|
296
337
|
end
|
297
338
|
|
@@ -318,25 +359,31 @@ db_namespace = namespace :db do
|
|
318
359
|
|
319
360
|
# desc "Recreate the test database from an existent schema.rb file"
|
320
361
|
task load_schema: %w(db:test:purge) do
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
ActiveRecord::Tasks::DatabaseTasks.
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
362
|
+
should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
|
363
|
+
ActiveRecord::Schema.verbose = false
|
364
|
+
ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
|
365
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :ruby)
|
366
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config.config, :ruby, filename, "test")
|
367
|
+
end
|
368
|
+
ensure
|
369
|
+
if should_reconnect
|
370
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations.default_hash(ActiveRecord::Tasks::DatabaseTasks.env))
|
329
371
|
end
|
330
372
|
end
|
331
373
|
|
332
374
|
# desc "Recreate the test database from an existent structure.sql file"
|
333
375
|
task load_structure: %w(db:test:purge) do
|
334
|
-
ActiveRecord::
|
376
|
+
ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
|
377
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :sql)
|
378
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config.config, :sql, filename, "test")
|
379
|
+
end
|
335
380
|
end
|
336
381
|
|
337
382
|
# desc "Empty the test database"
|
338
383
|
task purge: %w(load_config check_protected_environments) do
|
339
|
-
ActiveRecord::
|
384
|
+
ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
|
385
|
+
ActiveRecord::Tasks::DatabaseTasks.purge(db_config.config)
|
386
|
+
end
|
340
387
|
end
|
341
388
|
|
342
389
|
# desc 'Load the test schema'
|
@@ -360,6 +407,10 @@ namespace :railties do
|
|
360
407
|
if railtie.respond_to?(:paths) && (path = railtie.paths["db/migrate"].first)
|
361
408
|
railties[railtie.railtie_name] = path
|
362
409
|
end
|
410
|
+
|
411
|
+
unless ENV["MIGRATIONS_PATH"].blank?
|
412
|
+
railties[railtie.railtie_name] = railtie.root + ENV["MIGRATIONS_PATH"]
|
413
|
+
end
|
363
414
|
end
|
364
415
|
|
365
416
|
on_skip = Proc.new do |name, migration|
|
@@ -13,33 +13,37 @@ module ActiveRecord
|
|
13
13
|
class_attribute :aggregate_reflections, instance_writer: false, default: {}
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
when :has_many
|
22
|
-
HasManyReflection
|
23
|
-
when :has_one
|
24
|
-
HasOneReflection
|
25
|
-
when :belongs_to
|
26
|
-
BelongsToReflection
|
27
|
-
else
|
28
|
-
raise "Unsupported Macro: #{macro}"
|
29
|
-
end
|
16
|
+
class << self
|
17
|
+
def create(macro, name, scope, options, ar)
|
18
|
+
reflection = reflection_class_for(macro).new(name, scope, options, ar)
|
19
|
+
options[:through] ? ThroughReflection.new(reflection) : reflection
|
20
|
+
end
|
30
21
|
|
31
|
-
|
32
|
-
|
33
|
-
|
22
|
+
def add_reflection(ar, name, reflection)
|
23
|
+
ar.clear_reflections_cache
|
24
|
+
name = name.to_s
|
25
|
+
ar._reflections = ar._reflections.except(name).merge!(name => reflection)
|
26
|
+
end
|
34
27
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
ar._reflections = ar._reflections.except(name).merge!(name => reflection)
|
39
|
-
end
|
28
|
+
def add_aggregate_reflection(ar, name, reflection)
|
29
|
+
ar.aggregate_reflections = ar.aggregate_reflections.merge(name.to_s => reflection)
|
30
|
+
end
|
40
31
|
|
41
|
-
|
42
|
-
|
32
|
+
private
|
33
|
+
def reflection_class_for(macro)
|
34
|
+
case macro
|
35
|
+
when :composed_of
|
36
|
+
AggregateReflection
|
37
|
+
when :has_many
|
38
|
+
HasManyReflection
|
39
|
+
when :has_one
|
40
|
+
HasOneReflection
|
41
|
+
when :belongs_to
|
42
|
+
BelongsToReflection
|
43
|
+
else
|
44
|
+
raise "Unsupported Macro: #{macro}"
|
45
|
+
end
|
46
|
+
end
|
43
47
|
end
|
44
48
|
|
45
49
|
# \Reflection enables the ability to examine the associations and aggregations of
|
@@ -174,22 +178,26 @@ module ActiveRecord
|
|
174
178
|
scope ? [scope] : []
|
175
179
|
end
|
176
180
|
|
177
|
-
def
|
178
|
-
predicate_builder = predicate_builder(table)
|
179
|
-
scope_chain_items = join_scopes(table, predicate_builder)
|
180
|
-
klass_scope = klass_join_scope(table, predicate_builder)
|
181
|
-
|
181
|
+
def build_join_constraint(table, foreign_table)
|
182
182
|
key = join_keys.key
|
183
183
|
foreign_key = join_keys.foreign_key
|
184
184
|
|
185
|
-
|
185
|
+
constraint = table[key].eq(foreign_table[foreign_key])
|
186
186
|
|
187
|
-
if
|
188
|
-
|
187
|
+
if klass.finder_needs_type_condition?
|
188
|
+
table.create_and([constraint, klass.send(:type_condition, table)])
|
189
|
+
else
|
190
|
+
constraint
|
189
191
|
end
|
192
|
+
end
|
190
193
|
|
191
|
-
|
192
|
-
|
194
|
+
def join_scope(table, foreign_klass)
|
195
|
+
predicate_builder = predicate_builder(table)
|
196
|
+
scope_chain_items = join_scopes(table, predicate_builder)
|
197
|
+
klass_scope = klass_join_scope(table, predicate_builder)
|
198
|
+
|
199
|
+
if type
|
200
|
+
klass_scope.where!(type => foreign_klass.polymorphic_name)
|
193
201
|
end
|
194
202
|
|
195
203
|
scope_chain_items.inject(klass_scope, &:merge!)
|
@@ -413,7 +421,7 @@ module ActiveRecord
|
|
413
421
|
class AssociationReflection < MacroReflection #:nodoc:
|
414
422
|
def compute_class(name)
|
415
423
|
if polymorphic?
|
416
|
-
raise ArgumentError, "Polymorphic
|
424
|
+
raise ArgumentError, "Polymorphic associations do not support computing the class."
|
417
425
|
end
|
418
426
|
active_record.send(:compute_type, name)
|
419
427
|
end
|
@@ -604,9 +612,21 @@ module ActiveRecord
|
|
604
612
|
|
605
613
|
# returns either +nil+ or the inverse association name that it finds.
|
606
614
|
def automatic_inverse_of
|
607
|
-
|
608
|
-
|
615
|
+
return unless can_find_inverse_of_automatically?(self)
|
616
|
+
|
617
|
+
inverse_name_candidates =
|
618
|
+
if options[:as]
|
619
|
+
[options[:as]]
|
620
|
+
else
|
621
|
+
active_record_name = active_record.name.demodulize
|
622
|
+
[active_record_name, ActiveSupport::Inflector.pluralize(active_record_name)]
|
623
|
+
end
|
609
624
|
|
625
|
+
inverse_name_candidates.map! do |candidate|
|
626
|
+
ActiveSupport::Inflector.underscore(candidate).to_sym
|
627
|
+
end
|
628
|
+
|
629
|
+
inverse_name_candidates.detect do |inverse_name|
|
610
630
|
begin
|
611
631
|
reflection = klass._reflect_on_association(inverse_name)
|
612
632
|
rescue NameError
|
@@ -615,9 +635,7 @@ module ActiveRecord
|
|
615
635
|
reflection = false
|
616
636
|
end
|
617
637
|
|
618
|
-
|
619
|
-
return inverse_name
|
620
|
-
end
|
638
|
+
valid_inverse_reflection?(reflection)
|
621
639
|
end
|
622
640
|
end
|
623
641
|
|
@@ -961,16 +979,14 @@ module ActiveRecord
|
|
961
979
|
collect_join_reflections(seed + [self])
|
962
980
|
end
|
963
981
|
|
964
|
-
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
965
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
966
982
|
protected
|
967
|
-
attr_reader :delegate_reflection
|
968
|
-
|
969
983
|
def actual_source_reflection # FIXME: this is a horrible name
|
970
984
|
source_reflection.actual_source_reflection
|
971
985
|
end
|
972
986
|
|
973
987
|
private
|
988
|
+
attr_reader :delegate_reflection
|
989
|
+
|
974
990
|
def collect_join_reflections(seed)
|
975
991
|
a = source_reflection.add_as_source seed
|
976
992
|
if options[:source_type]
|
@@ -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
|