activerecord 6.0.0 → 6.1.0
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 +872 -582
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_record.rb +7 -13
- data/lib/active_record/aggregations.rb +1 -2
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations.rb +116 -13
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +49 -29
- data/lib/active_record/associations/association_scope.rb +17 -15
- data/lib/active_record/associations/belongs_to_association.rb +15 -5
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +9 -3
- data/lib/active_record/associations/builder/belongs_to.rb +10 -7
- data/lib/active_record/associations/builder/collection_association.rb +5 -4
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -3
- data/lib/active_record/associations/builder/has_many.rb +6 -2
- data/lib/active_record/associations/builder/has_one.rb +11 -14
- data/lib/active_record/associations/builder/singular_association.rb +1 -1
- data/lib/active_record/associations/collection_association.rb +25 -8
- data/lib/active_record/associations/collection_proxy.rb +14 -7
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +24 -3
- data/lib/active_record/associations/has_many_through_association.rb +10 -4
- data/lib/active_record/associations/has_one_association.rb +15 -1
- data/lib/active_record/associations/join_dependency.rb +77 -42
- data/lib/active_record/associations/join_dependency/join_association.rb +36 -14
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/preloader.rb +13 -8
- data/lib/active_record/associations/preloader/association.rb +51 -25
- data/lib/active_record/associations/preloader/through_association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_assignment.rb +10 -9
- data/lib/active_record/attribute_methods.rb +64 -54
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -10
- data/lib/active_record/attribute_methods/dirty.rb +3 -13
- data/lib/active_record/attribute_methods/primary_key.rb +6 -4
- data/lib/active_record/attribute_methods/query.rb +3 -6
- data/lib/active_record/attribute_methods/read.rb +8 -12
- data/lib/active_record/attribute_methods/serialization.rb +11 -6
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +12 -21
- data/lib/active_record/attributes.rb +32 -8
- data/lib/active_record/autosave_association.rb +63 -44
- data/lib/active_record/base.rb +2 -14
- data/lib/active_record/callbacks.rb +153 -24
- data/lib/active_record/coders/yaml_column.rb +1 -2
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +202 -138
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +86 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +4 -9
- data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +152 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -52
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +263 -107
- data/lib/active_record/connection_adapters/abstract/transaction.rb +82 -35
- data/lib/active_record/connection_adapters/abstract_adapter.rb +74 -76
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -115
- data/lib/active_record/connection_adapters/column.rb +15 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +30 -36
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -7
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +17 -13
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -13
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +21 -56
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- 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/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -6
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +7 -3
- 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 +72 -54
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +81 -57
- data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +38 -12
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -5
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -57
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +211 -81
- data/lib/active_record/core.rb +237 -69
- data/lib/active_record/counter_cache.rb +4 -1
- data/lib/active_record/database_configurations.rb +124 -85
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +52 -9
- data/lib/active_record/database_configurations/hash_config.rb +54 -8
- data/lib/active_record/database_configurations/url_config.rb +15 -41
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +2 -3
- data/lib/active_record/enum.rb +40 -16
- data/lib/active_record/errors.rb +47 -12
- data/lib/active_record/explain.rb +9 -5
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- data/lib/active_record/fixture_set/model_metadata.rb +1 -2
- data/lib/active_record/fixture_set/render_context.rb +1 -1
- data/lib/active_record/fixture_set/table_row.rb +2 -3
- data/lib/active_record/fixture_set/table_rows.rb +0 -1
- data/lib/active_record/fixtures.rb +54 -11
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +40 -21
- data/lib/active_record/insert_all.rb +39 -10
- data/lib/active_record/integration.rb +3 -5
- data/lib/active_record/internal_metadata.rb +16 -7
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +22 -17
- data/lib/active_record/locking/pessimistic.rb +6 -2
- data/lib/active_record/log_subscriber.rb +27 -9
- data/lib/active_record/middleware/database_selector.rb +4 -2
- data/lib/active_record/middleware/database_selector/resolver.rb +14 -14
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/migration.rb +114 -84
- data/lib/active_record/migration/command_recorder.rb +53 -45
- data/lib/active_record/migration/compatibility.rb +70 -20
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +120 -15
- data/lib/active_record/nested_attributes.rb +2 -5
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +50 -46
- data/lib/active_record/query_cache.rb +15 -5
- data/lib/active_record/querying.rb +12 -7
- data/lib/active_record/railtie.rb +65 -45
- data/lib/active_record/railties/databases.rake +267 -93
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +77 -63
- data/lib/active_record/relation.rb +108 -67
- data/lib/active_record/relation/batches.rb +38 -32
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/calculations.rb +102 -45
- data/lib/active_record/relation/delegation.rb +9 -7
- data/lib/active_record/relation/finder_methods.rb +55 -17
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +27 -26
- data/lib/active_record/relation/predicate_builder.rb +55 -35
- data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +340 -180
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -8
- data/lib/active_record/relation/where_clause.rb +104 -58
- data/lib/active_record/result.rb +41 -34
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +6 -17
- data/lib/active_record/schema_dumper.rb +34 -4
- data/lib/active_record/schema_migration.rb +2 -8
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/scoping/default.rb +0 -1
- data/lib/active_record/scoping/named.rb +7 -18
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +20 -4
- data/lib/active_record/store.rb +3 -3
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +39 -36
- data/lib/active_record/tasks/database_tasks.rb +139 -113
- data/lib/active_record/tasks/mysql_database_tasks.rb +34 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -27
- data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -10
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +38 -16
- data/lib/active_record/timestamp.rb +4 -7
- data/lib/active_record/touch_later.rb +20 -21
- data/lib/active_record/transactions.rb +22 -71
- data/lib/active_record/type.rb +8 -2
- 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 +6 -3
- data/lib/active_record/type/time.rb +10 -0
- 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 +0 -1
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +24 -4
- data/lib/arel.rb +15 -12
- data/lib/arel/attributes/attribute.rb +4 -0
- data/lib/arel/collectors/bind.rb +5 -0
- data/lib/arel/collectors/composite.rb +8 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/nodes.rb +3 -1
- data/lib/arel/nodes/binary.rb +82 -8
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/casted.rb +21 -9
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/node.rb +7 -6
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/sql_literal.rb +3 -0
- data/lib/arel/nodes/table_alias.rb +7 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/predications.rb +17 -24
- data/lib/arel/select_manager.rb +1 -2
- data/lib/arel/table.rb +13 -5
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel/visitors/dot.rb +14 -3
- data/lib/arel/visitors/mysql.rb +11 -1
- data/lib/arel/visitors/postgresql.rb +15 -5
- data/lib/arel/visitors/sqlite.rb +0 -1
- data/lib/arel/visitors/to_sql.rb +89 -79
- data/lib/arel/visitors/visitor.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 +6 -2
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
- data/lib/rails/generators/active_record/model/model_generator.rb +38 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- metadata +27 -24
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
@@ -3,6 +3,8 @@
|
|
3
3
|
require "benchmark"
|
4
4
|
require "set"
|
5
5
|
require "zlib"
|
6
|
+
require "active_support/core_ext/array/access"
|
7
|
+
require "active_support/core_ext/enumerable"
|
6
8
|
require "active_support/core_ext/module/attribute_accessors"
|
7
9
|
require "active_support/actionable_error"
|
8
10
|
|
@@ -18,7 +20,7 @@ module ActiveRecord
|
|
18
20
|
# For example the following migration is not reversible.
|
19
21
|
# Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.
|
20
22
|
#
|
21
|
-
# class IrreversibleMigrationExample < ActiveRecord::Migration[
|
23
|
+
# class IrreversibleMigrationExample < ActiveRecord::Migration[6.0]
|
22
24
|
# def change
|
23
25
|
# create_table :distributors do |t|
|
24
26
|
# t.string :zipcode
|
@@ -36,7 +38,7 @@ module ActiveRecord
|
|
36
38
|
#
|
37
39
|
# 1. Define <tt>#up</tt> and <tt>#down</tt> methods instead of <tt>#change</tt>:
|
38
40
|
#
|
39
|
-
# class ReversibleMigrationExample < ActiveRecord::Migration[
|
41
|
+
# class ReversibleMigrationExample < ActiveRecord::Migration[6.0]
|
40
42
|
# def up
|
41
43
|
# create_table :distributors do |t|
|
42
44
|
# t.string :zipcode
|
@@ -61,7 +63,7 @@ module ActiveRecord
|
|
61
63
|
#
|
62
64
|
# 2. Use the #reversible method in <tt>#change</tt> method:
|
63
65
|
#
|
64
|
-
# class ReversibleMigrationExample < ActiveRecord::Migration[
|
66
|
+
# class ReversibleMigrationExample < ActiveRecord::Migration[6.0]
|
65
67
|
# def change
|
66
68
|
# create_table :distributors do |t|
|
67
69
|
# t.string :zipcode
|
@@ -133,17 +135,34 @@ module ActiveRecord
|
|
133
135
|
|
134
136
|
action "Run pending migrations" do
|
135
137
|
ActiveRecord::Tasks::DatabaseTasks.migrate
|
138
|
+
|
139
|
+
if ActiveRecord::Base.dump_schema_after_migration
|
140
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(
|
141
|
+
ActiveRecord::Base.connection_db_config
|
142
|
+
)
|
143
|
+
end
|
136
144
|
end
|
137
145
|
|
138
146
|
def initialize(message = nil)
|
139
|
-
|
140
|
-
super("Migrations are pending. To resolve this issue, run:\n\n rails db:migrate RAILS_ENV=#{::Rails.env}")
|
141
|
-
elsif !message
|
142
|
-
super("Migrations are pending. To resolve this issue, run:\n\n rails db:migrate")
|
143
|
-
else
|
144
|
-
super
|
145
|
-
end
|
147
|
+
super(message || detailed_migration_message)
|
146
148
|
end
|
149
|
+
|
150
|
+
private
|
151
|
+
def detailed_migration_message
|
152
|
+
message = "Migrations are pending. To resolve this issue, run:\n\n bin/rails db:migrate"
|
153
|
+
message += " RAILS_ENV=#{::Rails.env}" if defined?(Rails.env)
|
154
|
+
message += "\n\n"
|
155
|
+
|
156
|
+
pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
|
157
|
+
|
158
|
+
message += "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}\n\n"
|
159
|
+
|
160
|
+
pending_migrations.each do |pending_migration|
|
161
|
+
message += "#{pending_migration.basename}\n"
|
162
|
+
end
|
163
|
+
|
164
|
+
message
|
165
|
+
end
|
147
166
|
end
|
148
167
|
|
149
168
|
class ConcurrentMigrationError < MigrationError #:nodoc:
|
@@ -157,7 +176,7 @@ module ActiveRecord
|
|
157
176
|
|
158
177
|
class NoEnvironmentInSchemaError < MigrationError #:nodoc:
|
159
178
|
def initialize
|
160
|
-
msg = "Environment data not found in the schema. To resolve this issue, run: \n\n rails db:environment:set"
|
179
|
+
msg = "Environment data not found in the schema. To resolve this issue, run: \n\n bin/rails db:environment:set"
|
161
180
|
if defined?(Rails.env)
|
162
181
|
super("#{msg} RAILS_ENV=#{::Rails.env}")
|
163
182
|
else
|
@@ -180,7 +199,7 @@ module ActiveRecord
|
|
180
199
|
msg = +"You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
|
181
200
|
msg << "You are running in `#{ current }` environment. "
|
182
201
|
msg << "If you are sure you want to continue, first set the environment using:\n\n"
|
183
|
-
msg << " rails db:environment:set"
|
202
|
+
msg << " bin/rails db:environment:set"
|
184
203
|
if defined?(Rails.env)
|
185
204
|
super("#{msg} RAILS_ENV=#{::Rails.env}\n\n")
|
186
205
|
else
|
@@ -189,6 +208,14 @@ module ActiveRecord
|
|
189
208
|
end
|
190
209
|
end
|
191
210
|
|
211
|
+
class EnvironmentStorageError < ActiveRecordError # :nodoc:
|
212
|
+
def initialize
|
213
|
+
msg = +"You are attempting to store the environment in a database where metadata is disabled.\n"
|
214
|
+
msg << "Check your database configuration to see if this is intended."
|
215
|
+
super(msg)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
192
219
|
# = Active Record Migrations
|
193
220
|
#
|
194
221
|
# Migrations can manage the evolution of a schema used by several physical
|
@@ -201,7 +228,7 @@ module ActiveRecord
|
|
201
228
|
#
|
202
229
|
# Example of a simple migration:
|
203
230
|
#
|
204
|
-
# class AddSsl < ActiveRecord::Migration[
|
231
|
+
# class AddSsl < ActiveRecord::Migration[6.0]
|
205
232
|
# def up
|
206
233
|
# add_column :accounts, :ssl_enabled, :boolean, default: true
|
207
234
|
# end
|
@@ -221,7 +248,7 @@ module ActiveRecord
|
|
221
248
|
#
|
222
249
|
# Example of a more complex migration that also needs to initialize data:
|
223
250
|
#
|
224
|
-
# class AddSystemSettings < ActiveRecord::Migration[
|
251
|
+
# class AddSystemSettings < ActiveRecord::Migration[6.0]
|
225
252
|
# def up
|
226
253
|
# create_table :system_settings do |t|
|
227
254
|
# t.string :name
|
@@ -337,7 +364,7 @@ module ActiveRecord
|
|
337
364
|
# The Rails package has several tools to help create and apply migrations.
|
338
365
|
#
|
339
366
|
# To generate a new migration, you can use
|
340
|
-
# rails generate migration MyNewMigration
|
367
|
+
# bin/rails generate migration MyNewMigration
|
341
368
|
#
|
342
369
|
# where MyNewMigration is the name of your migration. The generator will
|
343
370
|
# create an empty migration file <tt>timestamp_my_new_migration.rb</tt>
|
@@ -346,41 +373,36 @@ module ActiveRecord
|
|
346
373
|
#
|
347
374
|
# There is a special syntactic shortcut to generate migrations that add fields to a table.
|
348
375
|
#
|
349
|
-
# rails generate migration add_fieldname_to_tablename fieldname:string
|
376
|
+
# bin/rails generate migration add_fieldname_to_tablename fieldname:string
|
350
377
|
#
|
351
378
|
# This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
|
352
|
-
# class AddFieldnameToTablename < ActiveRecord::Migration[
|
379
|
+
# class AddFieldnameToTablename < ActiveRecord::Migration[6.0]
|
353
380
|
# def change
|
354
381
|
# add_column :tablenames, :fieldname, :string
|
355
382
|
# end
|
356
383
|
# end
|
357
384
|
#
|
358
385
|
# To run migrations against the currently configured database, use
|
359
|
-
# <tt>rails db:migrate</tt>. This will update the database by running all of the
|
386
|
+
# <tt>bin/rails db:migrate</tt>. This will update the database by running all of the
|
360
387
|
# pending migrations, creating the <tt>schema_migrations</tt> table
|
361
388
|
# (see "About the schema_migrations table" section below) if missing. It will also
|
362
389
|
# invoke the db:schema:dump command, which will update your db/schema.rb file
|
363
390
|
# to match the structure of your database.
|
364
391
|
#
|
365
392
|
# To roll the database back to a previous migration version, use
|
366
|
-
# <tt>rails db:rollback VERSION=X</tt> where <tt>X</tt> is the version to which
|
393
|
+
# <tt>bin/rails db:rollback VERSION=X</tt> where <tt>X</tt> is the version to which
|
367
394
|
# you wish to downgrade. Alternatively, you can also use the STEP option if you
|
368
|
-
# wish to rollback last few migrations. <tt>rails db:rollback STEP=2</tt> will rollback
|
395
|
+
# wish to rollback last few migrations. <tt>bin/rails db:rollback STEP=2</tt> will rollback
|
369
396
|
# the latest two migrations.
|
370
397
|
#
|
371
398
|
# If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
|
372
399
|
# that step will fail and you'll have some manual work to do.
|
373
400
|
#
|
374
|
-
# == Database support
|
375
|
-
#
|
376
|
-
# Migrations are currently supported in MySQL, PostgreSQL, SQLite,
|
377
|
-
# SQL Server, and Oracle (all supported databases except DB2).
|
378
|
-
#
|
379
401
|
# == More examples
|
380
402
|
#
|
381
403
|
# Not all migrations change the schema. Some just fix the data:
|
382
404
|
#
|
383
|
-
# class RemoveEmptyTags < ActiveRecord::Migration[
|
405
|
+
# class RemoveEmptyTags < ActiveRecord::Migration[6.0]
|
384
406
|
# def up
|
385
407
|
# Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
|
386
408
|
# end
|
@@ -393,7 +415,7 @@ module ActiveRecord
|
|
393
415
|
#
|
394
416
|
# Others remove columns when they migrate up instead of down:
|
395
417
|
#
|
396
|
-
# class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[
|
418
|
+
# class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[6.0]
|
397
419
|
# def up
|
398
420
|
# remove_column :items, :incomplete_items_count
|
399
421
|
# remove_column :items, :completed_items_count
|
@@ -407,7 +429,7 @@ module ActiveRecord
|
|
407
429
|
#
|
408
430
|
# And sometimes you need to do something in SQL not abstracted directly by migrations:
|
409
431
|
#
|
410
|
-
# class MakeJoinUnique < ActiveRecord::Migration[
|
432
|
+
# class MakeJoinUnique < ActiveRecord::Migration[6.0]
|
411
433
|
# def up
|
412
434
|
# execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
|
413
435
|
# end
|
@@ -424,7 +446,7 @@ module ActiveRecord
|
|
424
446
|
# <tt>Base#reset_column_information</tt> in order to ensure that the model has the
|
425
447
|
# latest column data from after the new column was added. Example:
|
426
448
|
#
|
427
|
-
# class AddPeopleSalary < ActiveRecord::Migration[
|
449
|
+
# class AddPeopleSalary < ActiveRecord::Migration[6.0]
|
428
450
|
# def up
|
429
451
|
# add_column :people, :salary, :integer
|
430
452
|
# Person.reset_column_information
|
@@ -482,7 +504,7 @@ module ActiveRecord
|
|
482
504
|
# To define a reversible migration, define the +change+ method in your
|
483
505
|
# migration like this:
|
484
506
|
#
|
485
|
-
# class TenderloveMigration < ActiveRecord::Migration[
|
507
|
+
# class TenderloveMigration < ActiveRecord::Migration[6.0]
|
486
508
|
# def change
|
487
509
|
# create_table(:horses) do |t|
|
488
510
|
# t.column :content, :text
|
@@ -512,7 +534,7 @@ module ActiveRecord
|
|
512
534
|
# can't execute inside a transaction though, and for these situations
|
513
535
|
# you can turn the automatic transactions off.
|
514
536
|
#
|
515
|
-
# class ChangeEnum < ActiveRecord::Migration[
|
537
|
+
# class ChangeEnum < ActiveRecord::Migration[6.0]
|
516
538
|
# disable_ddl_transaction!
|
517
539
|
#
|
518
540
|
# def up
|
@@ -525,6 +547,7 @@ module ActiveRecord
|
|
525
547
|
class Migration
|
526
548
|
autoload :CommandRecorder, "active_record/migration/command_recorder"
|
527
549
|
autoload :Compatibility, "active_record/migration/compatibility"
|
550
|
+
autoload :JoinTable, "active_record/migration/join_table"
|
528
551
|
|
529
552
|
# This must be defined before the inherited hook, below
|
530
553
|
class Current < Migration #:nodoc:
|
@@ -553,21 +576,36 @@ module ActiveRecord
|
|
553
576
|
# This class is used to verify that all migrations have been run before
|
554
577
|
# loading a web page if <tt>config.active_record.migration_error</tt> is set to :page_load
|
555
578
|
class CheckPending
|
556
|
-
def initialize(app)
|
579
|
+
def initialize(app, file_watcher: ActiveSupport::FileUpdateChecker)
|
557
580
|
@app = app
|
558
|
-
@
|
581
|
+
@needs_check = true
|
582
|
+
@mutex = Mutex.new
|
583
|
+
@file_watcher = file_watcher
|
559
584
|
end
|
560
585
|
|
561
586
|
def call(env)
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
587
|
+
@mutex.synchronize do
|
588
|
+
@watcher ||= build_watcher do
|
589
|
+
@needs_check = true
|
590
|
+
ActiveRecord::Migration.check_pending!(connection)
|
591
|
+
@needs_check = false
|
592
|
+
end
|
593
|
+
|
594
|
+
if @needs_check
|
595
|
+
@watcher.execute
|
596
|
+
else
|
597
|
+
@watcher.execute_if_updated
|
598
|
+
end
|
566
599
|
end
|
600
|
+
|
567
601
|
@app.call(env)
|
568
602
|
end
|
569
603
|
|
570
604
|
private
|
605
|
+
def build_watcher(&block)
|
606
|
+
paths = Array(connection.migration_context.migrations_paths)
|
607
|
+
@file_watcher.new([], paths.index_with(["rb"]), &block)
|
608
|
+
end
|
571
609
|
|
572
610
|
def connection
|
573
611
|
ActiveRecord::Base.connection
|
@@ -588,11 +626,11 @@ module ActiveRecord
|
|
588
626
|
end
|
589
627
|
|
590
628
|
def load_schema_if_pending!
|
591
|
-
|
629
|
+
current_db_config = Base.connection_db_config
|
592
630
|
all_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
|
593
631
|
|
594
632
|
needs_update = !all_configs.all? do |db_config|
|
595
|
-
Tasks::DatabaseTasks.schema_up_to_date?(db_config
|
633
|
+
Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord::Base.schema_format)
|
596
634
|
end
|
597
635
|
|
598
636
|
if needs_update
|
@@ -605,7 +643,7 @@ module ActiveRecord
|
|
605
643
|
end
|
606
644
|
|
607
645
|
# Establish a new connection, the old database may be gone (db:test:prepare uses purge)
|
608
|
-
Base.establish_connection(
|
646
|
+
Base.establish_connection(current_db_config)
|
609
647
|
|
610
648
|
check_pending!
|
611
649
|
end
|
@@ -619,6 +657,7 @@ module ActiveRecord
|
|
619
657
|
def method_missing(name, *args, &block) #:nodoc:
|
620
658
|
nearest_delegate.send(name, *args, &block)
|
621
659
|
end
|
660
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
622
661
|
|
623
662
|
def migrate(direction)
|
624
663
|
new.migrate direction
|
@@ -657,7 +696,7 @@ module ActiveRecord
|
|
657
696
|
# and create the table 'apples' on the way up, and the reverse
|
658
697
|
# on the way down.
|
659
698
|
#
|
660
|
-
# class FixTLMigration < ActiveRecord::Migration[
|
699
|
+
# class FixTLMigration < ActiveRecord::Migration[6.0]
|
661
700
|
# def change
|
662
701
|
# revert do
|
663
702
|
# create_table(:horses) do |t|
|
@@ -674,9 +713,9 @@ module ActiveRecord
|
|
674
713
|
# Or equivalently, if +TenderloveMigration+ is defined as in the
|
675
714
|
# documentation for Migration:
|
676
715
|
#
|
677
|
-
# require_relative
|
716
|
+
# require_relative "20121212123456_tenderlove_migration"
|
678
717
|
#
|
679
|
-
# class FixupTLMigration < ActiveRecord::Migration[
|
718
|
+
# class FixupTLMigration < ActiveRecord::Migration[6.0]
|
680
719
|
# def change
|
681
720
|
# revert TenderloveMigration
|
682
721
|
#
|
@@ -727,7 +766,7 @@ module ActiveRecord
|
|
727
766
|
# when the three columns 'first_name', 'last_name' and 'full_name' exist,
|
728
767
|
# even when migrating down:
|
729
768
|
#
|
730
|
-
# class SplitNameMigration < ActiveRecord::Migration[
|
769
|
+
# class SplitNameMigration < ActiveRecord::Migration[6.0]
|
731
770
|
# def change
|
732
771
|
# add_column :users, :first_name, :string
|
733
772
|
# add_column :users, :last_name, :string
|
@@ -755,7 +794,7 @@ module ActiveRecord
|
|
755
794
|
# In the following example, the new column +published+ will be given
|
756
795
|
# the value +true+ for all existing records.
|
757
796
|
#
|
758
|
-
# class AddPublishedToPosts < ActiveRecord::Migration[
|
797
|
+
# class AddPublishedToPosts < ActiveRecord::Migration[6.0]
|
759
798
|
# def change
|
760
799
|
# add_column :posts, :published, :boolean, default: false
|
761
800
|
# up_only do
|
@@ -828,7 +867,7 @@ module ActiveRecord
|
|
828
867
|
change
|
829
868
|
end
|
830
869
|
else
|
831
|
-
|
870
|
+
public_send(direction)
|
832
871
|
end
|
833
872
|
ensure
|
834
873
|
@connection = nil
|
@@ -890,6 +929,7 @@ module ActiveRecord
|
|
890
929
|
connection.send(method, *arguments, &block)
|
891
930
|
end
|
892
931
|
end
|
932
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
893
933
|
|
894
934
|
def copy(destination, sources, options = {})
|
895
935
|
copied = []
|
@@ -994,14 +1034,9 @@ module ActiveRecord
|
|
994
1034
|
File.basename(filename)
|
995
1035
|
end
|
996
1036
|
|
997
|
-
def mtime
|
998
|
-
File.mtime filename
|
999
|
-
end
|
1000
|
-
|
1001
1037
|
delegate :migrate, :announce, :write, :disable_ddl_transaction, to: :migration
|
1002
1038
|
|
1003
1039
|
private
|
1004
|
-
|
1005
1040
|
def migration
|
1006
1041
|
@migration ||= load_migration
|
1007
1042
|
end
|
@@ -1012,16 +1047,6 @@ module ActiveRecord
|
|
1012
1047
|
end
|
1013
1048
|
end
|
1014
1049
|
|
1015
|
-
class NullMigration < MigrationProxy #:nodoc:
|
1016
|
-
def initialize
|
1017
|
-
super(nil, 0, nil, nil)
|
1018
|
-
end
|
1019
|
-
|
1020
|
-
def mtime
|
1021
|
-
0
|
1022
|
-
end
|
1023
|
-
end
|
1024
|
-
|
1025
1050
|
class MigrationContext #:nodoc:
|
1026
1051
|
attr_reader :migrations_paths, :schema_migration
|
1027
1052
|
|
@@ -1100,10 +1125,6 @@ module ActiveRecord
|
|
1100
1125
|
migrations.any?
|
1101
1126
|
end
|
1102
1127
|
|
1103
|
-
def last_migration #:nodoc:
|
1104
|
-
migrations.last || NullMigration.new
|
1105
|
-
end
|
1106
|
-
|
1107
1128
|
def migrations
|
1108
1129
|
migrations = migration_files.map do |file|
|
1109
1130
|
version, name, scope = parse_migration_filename(file)
|
@@ -1144,6 +1165,7 @@ module ActiveRecord
|
|
1144
1165
|
end
|
1145
1166
|
|
1146
1167
|
def last_stored_environment
|
1168
|
+
return nil unless ActiveRecord::InternalMetadata.enabled?
|
1147
1169
|
return nil if current_version == 0
|
1148
1170
|
raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
|
1149
1171
|
|
@@ -1178,7 +1200,7 @@ module ActiveRecord
|
|
1178
1200
|
|
1179
1201
|
finish = migrator.migrations[start_index + steps]
|
1180
1202
|
version = finish ? finish.version : 0
|
1181
|
-
|
1203
|
+
public_send(direction, version)
|
1182
1204
|
end
|
1183
1205
|
end
|
1184
1206
|
|
@@ -1261,12 +1283,11 @@ module ActiveRecord
|
|
1261
1283
|
end
|
1262
1284
|
|
1263
1285
|
private
|
1264
|
-
|
1265
1286
|
# Used for running a specific migration.
|
1266
1287
|
def run_without_lock
|
1267
1288
|
migration = migrations.detect { |m| m.version == @target_version }
|
1268
1289
|
raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
|
1269
|
-
result = execute_migration_in_transaction(migration
|
1290
|
+
result = execute_migration_in_transaction(migration)
|
1270
1291
|
|
1271
1292
|
record_environment
|
1272
1293
|
result
|
@@ -1278,10 +1299,7 @@ module ActiveRecord
|
|
1278
1299
|
raise UnknownMigrationVersionError.new(@target_version)
|
1279
1300
|
end
|
1280
1301
|
|
1281
|
-
result = runnable.each
|
1282
|
-
execute_migration_in_transaction(migration, @direction)
|
1283
|
-
end
|
1284
|
-
|
1302
|
+
result = runnable.each(&method(:execute_migration_in_transaction))
|
1285
1303
|
record_environment
|
1286
1304
|
result
|
1287
1305
|
end
|
@@ -1301,14 +1319,14 @@ module ActiveRecord
|
|
1301
1319
|
@target_version && @target_version != 0 && !target
|
1302
1320
|
end
|
1303
1321
|
|
1304
|
-
def execute_migration_in_transaction(migration
|
1322
|
+
def execute_migration_in_transaction(migration)
|
1305
1323
|
return if down? && !migrated.include?(migration.version.to_i)
|
1306
1324
|
return if up? && migrated.include?(migration.version.to_i)
|
1307
1325
|
|
1308
1326
|
Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
|
1309
1327
|
|
1310
1328
|
ddl_transaction(migration) do
|
1311
|
-
migration.migrate(direction)
|
1329
|
+
migration.migrate(@direction)
|
1312
1330
|
record_version_state_after_migrating(migration.version)
|
1313
1331
|
end
|
1314
1332
|
rescue => e
|
@@ -1375,19 +1393,31 @@ module ActiveRecord
|
|
1375
1393
|
|
1376
1394
|
def with_advisory_lock
|
1377
1395
|
lock_id = generate_migrator_advisory_lock_id
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
ConcurrentMigrationError
|
1387
|
-
|
1396
|
+
|
1397
|
+
with_advisory_lock_connection do |connection|
|
1398
|
+
got_lock = connection.get_advisory_lock(lock_id)
|
1399
|
+
raise ConcurrentMigrationError unless got_lock
|
1400
|
+
load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
|
1401
|
+
yield
|
1402
|
+
ensure
|
1403
|
+
if got_lock && !connection.release_advisory_lock(lock_id)
|
1404
|
+
raise ConcurrentMigrationError.new(
|
1405
|
+
ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
|
1406
|
+
)
|
1407
|
+
end
|
1388
1408
|
end
|
1389
1409
|
end
|
1390
1410
|
|
1411
|
+
def with_advisory_lock_connection
|
1412
|
+
pool = ActiveRecord::ConnectionAdapters::ConnectionHandler.new.establish_connection(
|
1413
|
+
ActiveRecord::Base.connection_db_config
|
1414
|
+
)
|
1415
|
+
|
1416
|
+
pool.with_connection { |connection| yield(connection) }
|
1417
|
+
ensure
|
1418
|
+
pool&.disconnect!
|
1419
|
+
end
|
1420
|
+
|
1391
1421
|
MIGRATOR_SALT = 2053462845
|
1392
1422
|
def generate_migrator_advisory_lock_id
|
1393
1423
|
db_name_hash = Zlib.crc32(Base.connection.current_database)
|