activerecord 5.1.0 → 5.2.0.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.

Files changed (260) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +410 -530
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/examples/performance.rb +2 -0
  6. data/examples/simple.rb +2 -0
  7. data/lib/active_record/aggregations.rb +6 -5
  8. data/lib/active_record/association_relation.rb +4 -2
  9. data/lib/active_record/associations/alias_tracker.rb +23 -32
  10. data/lib/active_record/associations/association.rb +20 -21
  11. data/lib/active_record/associations/association_scope.rb +49 -49
  12. data/lib/active_record/associations/belongs_to_association.rb +12 -10
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +4 -7
  14. data/lib/active_record/associations/builder/association.rb +4 -7
  15. data/lib/active_record/associations/builder/belongs_to.rb +10 -6
  16. data/lib/active_record/associations/builder/collection_association.rb +1 -1
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  18. data/lib/active_record/associations/builder/has_many.rb +2 -0
  19. data/lib/active_record/associations/builder/has_one.rb +2 -0
  20. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  21. data/lib/active_record/associations/collection_association.rb +50 -41
  22. data/lib/active_record/associations/collection_proxy.rb +22 -39
  23. data/lib/active_record/associations/foreign_association.rb +2 -0
  24. data/lib/active_record/associations/has_many_association.rb +4 -2
  25. data/lib/active_record/associations/has_many_through_association.rb +12 -18
  26. data/lib/active_record/associations/has_one_association.rb +5 -1
  27. data/lib/active_record/associations/has_one_through_association.rb +8 -7
  28. data/lib/active_record/associations/join_dependency/join_association.rb +17 -64
  29. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  30. data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
  31. data/lib/active_record/associations/join_dependency.rb +27 -44
  32. data/lib/active_record/associations/preloader/association.rb +53 -92
  33. data/lib/active_record/associations/preloader/through_association.rb +72 -73
  34. data/lib/active_record/associations/preloader.rb +17 -37
  35. data/lib/active_record/associations/singular_association.rb +14 -10
  36. data/lib/active_record/associations/through_association.rb +26 -11
  37. data/lib/active_record/associations.rb +68 -76
  38. data/lib/active_record/attribute_assignment.rb +2 -0
  39. data/lib/active_record/attribute_decorators.rb +3 -2
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  41. data/lib/active_record/attribute_methods/dirty.rb +24 -214
  42. data/lib/active_record/attribute_methods/primary_key.rb +10 -13
  43. data/lib/active_record/attribute_methods/query.rb +2 -0
  44. data/lib/active_record/attribute_methods/read.rb +8 -2
  45. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  47. data/lib/active_record/attribute_methods/write.rb +22 -19
  48. data/lib/active_record/attribute_methods.rb +48 -12
  49. data/lib/active_record/attributes.rb +7 -6
  50. data/lib/active_record/autosave_association.rb +8 -11
  51. data/lib/active_record/base.rb +2 -0
  52. data/lib/active_record/callbacks.rb +8 -6
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +2 -0
  55. data/lib/active_record/collection_cache_key.rb +14 -10
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +175 -33
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +8 -2
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -24
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +58 -3
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +165 -85
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +83 -97
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +118 -180
  69. data/lib/active_record/connection_adapters/column.rb +4 -2
  70. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -17
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -23
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  98. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -2
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -1
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +269 -126
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +64 -85
  116. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  118. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  119. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +18 -0
  120. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  122. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  123. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
  124. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +92 -95
  125. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  126. data/lib/active_record/connection_handling.rb +4 -2
  127. data/lib/active_record/core.rb +39 -60
  128. data/lib/active_record/counter_cache.rb +3 -2
  129. data/lib/active_record/define_callbacks.rb +5 -3
  130. data/lib/active_record/dynamic_matchers.rb +9 -9
  131. data/lib/active_record/enum.rb +17 -13
  132. data/lib/active_record/errors.rb +42 -3
  133. data/lib/active_record/explain.rb +3 -1
  134. data/lib/active_record/explain_registry.rb +2 -0
  135. data/lib/active_record/explain_subscriber.rb +2 -0
  136. data/lib/active_record/fixture_set/file.rb +2 -0
  137. data/lib/active_record/fixtures.rb +67 -60
  138. data/lib/active_record/gem_version.rb +4 -2
  139. data/lib/active_record/inheritance.rb +9 -9
  140. data/lib/active_record/integration.rb +58 -19
  141. data/lib/active_record/internal_metadata.rb +2 -0
  142. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  143. data/lib/active_record/locking/optimistic.rb +8 -6
  144. data/lib/active_record/locking/pessimistic.rb +9 -6
  145. data/lib/active_record/log_subscriber.rb +46 -4
  146. data/lib/active_record/migration/command_recorder.rb +11 -9
  147. data/lib/active_record/migration/compatibility.rb +74 -22
  148. data/lib/active_record/migration/join_table.rb +2 -0
  149. data/lib/active_record/migration.rb +181 -137
  150. data/lib/active_record/model_schema.rb +73 -58
  151. data/lib/active_record/nested_attributes.rb +18 -6
  152. data/lib/active_record/no_touching.rb +3 -1
  153. data/lib/active_record/null_relation.rb +2 -0
  154. data/lib/active_record/persistence.rb +153 -18
  155. data/lib/active_record/query_cache.rb +17 -12
  156. data/lib/active_record/querying.rb +4 -2
  157. data/lib/active_record/railtie.rb +61 -3
  158. data/lib/active_record/railties/console_sandbox.rb +2 -0
  159. data/lib/active_record/railties/controller_runtime.rb +2 -0
  160. data/lib/active_record/railties/databases.rake +47 -37
  161. data/lib/active_record/readonly_attributes.rb +3 -2
  162. data/lib/active_record/reflection.rb +131 -204
  163. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  164. data/lib/active_record/relation/batches.rb +32 -17
  165. data/lib/active_record/relation/calculations.rb +58 -20
  166. data/lib/active_record/relation/delegation.rb +10 -29
  167. data/lib/active_record/relation/finder_methods.rb +74 -85
  168. data/lib/active_record/relation/from_clause.rb +2 -8
  169. data/lib/active_record/relation/merger.rb +51 -20
  170. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  171. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  172. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  173. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  174. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +54 -0
  175. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
  176. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  177. data/lib/active_record/relation/predicate_builder.rb +53 -78
  178. data/lib/active_record/relation/query_attribute.rb +9 -2
  179. data/lib/active_record/relation/query_methods.rb +101 -95
  180. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  181. data/lib/active_record/relation/spawn_methods.rb +3 -1
  182. data/lib/active_record/relation/where_clause.rb +65 -67
  183. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  184. data/lib/active_record/relation.rb +99 -202
  185. data/lib/active_record/result.rb +2 -0
  186. data/lib/active_record/runtime_registry.rb +2 -0
  187. data/lib/active_record/sanitization.rb +129 -121
  188. data/lib/active_record/schema.rb +4 -2
  189. data/lib/active_record/schema_dumper.rb +36 -26
  190. data/lib/active_record/schema_migration.rb +2 -0
  191. data/lib/active_record/scoping/default.rb +10 -7
  192. data/lib/active_record/scoping/named.rb +38 -12
  193. data/lib/active_record/scoping.rb +12 -10
  194. data/lib/active_record/secure_token.rb +2 -0
  195. data/lib/active_record/serialization.rb +2 -0
  196. data/lib/active_record/statement_cache.rb +22 -12
  197. data/lib/active_record/store.rb +3 -1
  198. data/lib/active_record/suppressor.rb +2 -0
  199. data/lib/active_record/table_metadata.rb +12 -3
  200. data/lib/active_record/tasks/database_tasks.rb +37 -25
  201. data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
  202. data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
  203. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  204. data/lib/active_record/timestamp.rb +5 -5
  205. data/lib/active_record/touch_later.rb +2 -0
  206. data/lib/active_record/transactions.rb +9 -7
  207. data/lib/active_record/translation.rb +2 -0
  208. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  209. data/lib/active_record/type/date.rb +2 -0
  210. data/lib/active_record/type/date_time.rb +2 -0
  211. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  212. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  213. data/lib/active_record/type/internal/timezone.rb +2 -0
  214. data/lib/active_record/type/json.rb +30 -0
  215. data/lib/active_record/type/serialized.rb +2 -0
  216. data/lib/active_record/type/text.rb +2 -0
  217. data/lib/active_record/type/time.rb +2 -0
  218. data/lib/active_record/type/type_map.rb +2 -0
  219. data/lib/active_record/type/unsigned_integer.rb +2 -0
  220. data/lib/active_record/type.rb +4 -1
  221. data/lib/active_record/type_caster/connection.rb +2 -0
  222. data/lib/active_record/type_caster/map.rb +3 -1
  223. data/lib/active_record/type_caster.rb +2 -0
  224. data/lib/active_record/validations/absence.rb +2 -0
  225. data/lib/active_record/validations/associated.rb +2 -0
  226. data/lib/active_record/validations/length.rb +2 -0
  227. data/lib/active_record/validations/presence.rb +2 -0
  228. data/lib/active_record/validations/uniqueness.rb +35 -5
  229. data/lib/active_record/validations.rb +2 -0
  230. data/lib/active_record/version.rb +2 -0
  231. data/lib/active_record.rb +11 -4
  232. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  233. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  234. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  235. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  236. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  237. data/lib/rails/generators/active_record/migration.rb +2 -0
  238. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  239. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  241. data/lib/rails/generators/active_record.rb +3 -1
  242. metadata +25 -37
  243. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  244. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  245. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  246. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  247. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  248. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  249. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  250. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  251. data/lib/active_record/attribute.rb +0 -240
  252. data/lib/active_record/attribute_mutation_tracker.rb +0 -113
  253. data/lib/active_record/attribute_set/builder.rb +0 -124
  254. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  255. data/lib/active_record/attribute_set.rb +0 -113
  256. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  257. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  258. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  259. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  260. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "set"
2
4
  require "zlib"
3
5
  require "active_support/core_ext/module/attribute_accessors"
@@ -157,7 +159,7 @@ module ActiveRecord
157
159
 
158
160
  class ProtectedEnvironmentError < ActiveRecordError #:nodoc:
159
161
  def initialize(env = "production")
160
- msg = "You are attempting to run a destructive action against your '#{env}' database.\n"
162
+ msg = "You are attempting to run a destructive action against your '#{env}' database.\n".dup
161
163
  msg << "If you are sure you want to continue, run the same command with the environment variable:\n"
162
164
  msg << "DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
163
165
  super(msg)
@@ -166,7 +168,7 @@ module ActiveRecord
166
168
 
167
169
  class EnvironmentMismatchError < ActiveRecordError
168
170
  def initialize(current: nil, stored: nil)
169
- msg = "You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
171
+ msg = "You are attempting to modify a database that was last run in `#{ stored }` environment.\n".dup
170
172
  msg << "You are running in `#{ current }` environment. "
171
173
  msg << "If you are sure you want to continue, first set the environment using:\n\n"
172
174
  msg << " bin/rails db:environment:set"
@@ -352,9 +354,9 @@ module ActiveRecord
352
354
  # to match the structure of your database.
353
355
  #
354
356
  # To roll the database back to a previous migration version, use
355
- # <tt>rails db:migrate VERSION=X</tt> where <tt>X</tt> is the version to which
357
+ # <tt>rails db:rollback VERSION=X</tt> where <tt>X</tt> is the version to which
356
358
  # you wish to downgrade. Alternatively, you can also use the STEP option if you
357
- # wish to rollback last few migrations. <tt>rails db:migrate STEP=2</tt> will rollback
359
+ # wish to rollback last few migrations. <tt>rails db:rollback STEP=2</tt> will rollback
358
360
  # the latest two migrations.
359
361
  #
360
362
  # If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
@@ -548,7 +550,7 @@ module ActiveRecord
548
550
  end
549
551
 
550
552
  def call(env)
551
- mtime = ActiveRecord::Migrator.last_migration.mtime.to_i
553
+ mtime = ActiveRecord::Base.connection.migration_context.last_migration.mtime.to_i
552
554
  if @last_check < mtime
553
555
  ActiveRecord::Migration.check_pending!(connection)
554
556
  @last_check = mtime
@@ -573,13 +575,14 @@ module ActiveRecord
573
575
 
574
576
  # Raises <tt>ActiveRecord::PendingMigrationError</tt> error if any migrations are pending.
575
577
  def check_pending!(connection = Base.connection)
576
- raise ActiveRecord::PendingMigrationError if ActiveRecord::Migrator.needs_migration?(connection)
578
+ raise ActiveRecord::PendingMigrationError if connection.migration_context.needs_migration?
577
579
  end
578
580
 
579
581
  def load_schema_if_pending!
580
- if ActiveRecord::Migrator.needs_migration? || !ActiveRecord::Migrator.any_migrations?
582
+ if Base.connection.migration_context.needs_migration? || !Base.connection.migration_context.any_migrations?
581
583
  # Roundtrip to Rake to allow plugins to hook into database initialization.
582
- FileUtils.cd Rails.root do
584
+ root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
585
+ FileUtils.cd(root) do
583
586
  current_config = Base.connection_config
584
587
  Base.clear_all_connections!
585
588
  system("bin/rails db:test:prepare")
@@ -731,6 +734,24 @@ module ActiveRecord
731
734
  execute_block { yield helper }
732
735
  end
733
736
 
737
+ # Used to specify an operation that is only run when migrating up
738
+ # (for example, populating a new column with its initial values).
739
+ #
740
+ # In the following example, the new column +published+ will be given
741
+ # the value +true+ for all existing records.
742
+ #
743
+ # class AddPublishedToPosts < ActiveRecord::Migration[5.2]
744
+ # def change
745
+ # add_column :posts, :published, :boolean, default: false
746
+ # up_only do
747
+ # execute "update posts set published = 'true'"
748
+ # end
749
+ # end
750
+ # end
751
+ def up_only
752
+ execute_block { yield } unless reverting?
753
+ end
754
+
734
755
  # Runs the given migration classes.
735
756
  # Last argument can specify options:
736
757
  # - :direction (default is :up)
@@ -855,23 +876,25 @@ module ActiveRecord
855
876
 
856
877
  FileUtils.mkdir_p(destination) unless File.exist?(destination)
857
878
 
858
- destination_migrations = ActiveRecord::Migrator.migrations(destination)
879
+ destination_migrations = ActiveRecord::MigrationContext.new(destination).migrations
859
880
  last = destination_migrations.last
860
881
  sources.each do |scope, path|
861
- source_migrations = ActiveRecord::Migrator.migrations(path)
882
+ source_migrations = ActiveRecord::MigrationContext.new(path).migrations
862
883
 
863
884
  source_migrations.each do |migration|
864
885
  source = File.binread(migration.filename)
865
886
  inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n"
866
- if /\A#.*\b(?:en)?coding:\s*\S+/ =~ source
887
+ magic_comments = "".dup
888
+ loop do
867
889
  # If we have a magic comment in the original migration,
868
890
  # insert our comment after the first newline(end of the magic comment line)
869
891
  # so the magic keep working.
870
892
  # Note that magic comments must be at the first line(except sh-bang).
871
- source[/\n/] = "\n#{inserted_comment}"
872
- else
873
- source = "#{inserted_comment}#{source}"
893
+ source.sub!(/\A(?:#.*\b(?:en)?coding:\s*\S+|#\s*frozen_string_literal:\s*(?:true|false)).*\n/) do |magic_comment|
894
+ magic_comments << magic_comment; ""
895
+ end || break
874
896
  end
897
+ source = "#{magic_comments}#{inserted_comment}#{source}"
875
898
 
876
899
  if duplicate = destination_migrations.detect { |m| m.name == migration.name }
877
900
  if options[:on_skip] && duplicate.scope != scope.to_s
@@ -974,146 +997,184 @@ module ActiveRecord
974
997
  end
975
998
  end
976
999
 
977
- class Migrator#:nodoc:
978
- class << self
979
- attr_writer :migrations_paths
980
- alias :migrations_path= :migrations_paths=
981
-
982
- def migrate(migrations_paths, target_version = nil, &block)
983
- case
984
- when target_version.nil?
985
- up(migrations_paths, target_version, &block)
986
- when current_version == 0 && target_version == 0
987
- []
988
- when current_version > target_version
989
- down(migrations_paths, target_version, &block)
990
- else
991
- up(migrations_paths, target_version, &block)
992
- end
993
- end
1000
+ class MigrationContext # :nodoc:
1001
+ attr_reader :migrations_paths
994
1002
 
995
- def rollback(migrations_paths, steps = 1)
996
- move(:down, migrations_paths, steps)
997
- end
1003
+ def initialize(migrations_paths)
1004
+ @migrations_paths = migrations_paths
1005
+ end
998
1006
 
999
- def forward(migrations_paths, steps = 1)
1000
- move(:up, migrations_paths, steps)
1007
+ def migrate(target_version = nil, &block)
1008
+ case
1009
+ when target_version.nil?
1010
+ up(target_version, &block)
1011
+ when current_version == 0 && target_version == 0
1012
+ []
1013
+ when current_version > target_version
1014
+ down(target_version, &block)
1015
+ else
1016
+ up(target_version, &block)
1001
1017
  end
1018
+ end
1019
+
1020
+ def rollback(steps = 1)
1021
+ move(:down, steps)
1022
+ end
1002
1023
 
1003
- def up(migrations_paths, target_version = nil)
1004
- migrations = migrations(migrations_paths)
1005
- migrations.select! { |m| yield m } if block_given?
1024
+ def forward(steps = 1)
1025
+ move(:up, steps)
1026
+ end
1006
1027
 
1007
- new(:up, migrations, target_version).migrate
1028
+ def up(target_version = nil)
1029
+ selected_migrations = if block_given?
1030
+ migrations.select { |m| yield m }
1031
+ else
1032
+ migrations
1008
1033
  end
1009
1034
 
1010
- def down(migrations_paths, target_version = nil)
1011
- migrations = migrations(migrations_paths)
1012
- migrations.select! { |m| yield m } if block_given?
1035
+ Migrator.new(:up, selected_migrations, target_version).migrate
1036
+ end
1013
1037
 
1014
- new(:down, migrations, target_version).migrate
1038
+ def down(target_version = nil)
1039
+ selected_migrations = if block_given?
1040
+ migrations.select { |m| yield m }
1041
+ else
1042
+ migrations
1015
1043
  end
1016
1044
 
1017
- def run(direction, migrations_paths, target_version)
1018
- new(direction, migrations(migrations_paths), target_version).run
1019
- end
1045
+ Migrator.new(:down, selected_migrations, target_version).migrate
1046
+ end
1020
1047
 
1021
- def open(migrations_paths)
1022
- new(:up, migrations(migrations_paths), nil)
1023
- end
1048
+ def run(direction, target_version)
1049
+ Migrator.new(direction, migrations, target_version).run
1050
+ end
1024
1051
 
1025
- def schema_migrations_table_name
1026
- SchemaMigration.table_name
1027
- end
1028
- deprecate :schema_migrations_table_name
1052
+ def open
1053
+ Migrator.new(:up, migrations, nil)
1054
+ end
1029
1055
 
1030
- def get_all_versions(connection = Base.connection)
1031
- if SchemaMigration.table_exists?
1032
- SchemaMigration.all_versions.map(&:to_i)
1033
- else
1034
- []
1035
- end
1056
+ def get_all_versions
1057
+ if SchemaMigration.table_exists?
1058
+ SchemaMigration.all_versions.map(&:to_i)
1059
+ else
1060
+ []
1036
1061
  end
1062
+ end
1037
1063
 
1038
- def current_version(connection = Base.connection)
1039
- get_all_versions(connection).max || 0
1040
- end
1064
+ def current_version
1065
+ get_all_versions.max || 0
1066
+ rescue ActiveRecord::NoDatabaseError
1067
+ end
1041
1068
 
1042
- def needs_migration?(connection = Base.connection)
1043
- (migrations(migrations_paths).collect(&:version) - get_all_versions(connection)).size > 0
1044
- end
1069
+ def needs_migration?
1070
+ (migrations.collect(&:version) - get_all_versions).size > 0
1071
+ end
1045
1072
 
1046
- def any_migrations?
1047
- migrations(migrations_paths).any?
1048
- end
1073
+ def any_migrations?
1074
+ migrations.any?
1075
+ end
1049
1076
 
1050
- def last_migration #:nodoc:
1051
- migrations(migrations_paths).last || NullMigration.new
1052
- end
1077
+ def last_migration #:nodoc:
1078
+ migrations.last || NullMigration.new
1079
+ end
1053
1080
 
1054
- def migrations_paths
1055
- @migrations_paths ||= ["db/migrate"]
1056
- # just to not break things if someone uses: migrations_path = some_string
1057
- Array(@migrations_paths)
1058
- end
1081
+ def parse_migration_filename(filename) # :nodoc:
1082
+ File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
1083
+ end
1059
1084
 
1060
- def parse_migration_filename(filename) # :nodoc:
1061
- File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
1085
+ def migrations
1086
+ migrations = migration_files.map do |file|
1087
+ version, name, scope = parse_migration_filename(file)
1088
+ raise IllegalMigrationNameError.new(file) unless version
1089
+ version = version.to_i
1090
+ name = name.camelize
1091
+
1092
+ MigrationProxy.new(name, version, file, scope)
1062
1093
  end
1063
1094
 
1064
- def migrations(paths)
1065
- paths = Array(paths)
1095
+ migrations.sort_by(&:version)
1096
+ end
1066
1097
 
1067
- migrations = migration_files(paths).map do |file|
1068
- version, name, scope = parse_migration_filename(file)
1069
- raise IllegalMigrationNameError.new(file) unless version
1070
- version = version.to_i
1071
- name = name.camelize
1098
+ def migrations_status
1099
+ db_list = ActiveRecord::SchemaMigration.normalized_versions
1072
1100
 
1073
- MigrationProxy.new(name, version, file, scope)
1074
- end
1101
+ file_list = migration_files.map do |file|
1102
+ version, name, scope = parse_migration_filename(file)
1103
+ raise IllegalMigrationNameError.new(file) unless version
1104
+ version = ActiveRecord::SchemaMigration.normalize_migration_number(version)
1105
+ status = db_list.delete(version) ? "up" : "down"
1106
+ [status, version, (name + scope).humanize]
1107
+ end.compact
1075
1108
 
1076
- migrations.sort_by(&:version)
1109
+ db_list.map! do |version|
1110
+ ["up", version, "********** NO FILE **********"]
1077
1111
  end
1078
1112
 
1079
- def migrations_status(paths)
1080
- paths = Array(paths)
1113
+ (db_list + file_list).sort_by { |_, version, _| version }
1114
+ end
1081
1115
 
1082
- db_list = ActiveRecord::SchemaMigration.normalized_versions
1116
+ def migration_files
1117
+ paths = Array(migrations_paths)
1118
+ Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
1119
+ end
1120
+
1121
+ def current_environment
1122
+ ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
1123
+ end
1083
1124
 
1084
- file_list = migration_files(paths).map do |file|
1085
- version, name, scope = parse_migration_filename(file)
1086
- raise IllegalMigrationNameError.new(file) unless version
1087
- version = ActiveRecord::SchemaMigration.normalize_migration_number(version)
1088
- status = db_list.delete(version) ? "up" : "down"
1089
- [status, version, (name + scope).humanize]
1090
- end.compact
1125
+ def protected_environment?
1126
+ ActiveRecord::Base.protected_environments.include?(last_stored_environment) if last_stored_environment
1127
+ end
1128
+
1129
+ def last_stored_environment
1130
+ return nil if current_version == 0
1131
+ raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
1132
+
1133
+ environment = ActiveRecord::InternalMetadata[:environment]
1134
+ raise NoEnvironmentInSchemaError unless environment
1135
+ environment
1136
+ end
1091
1137
 
1092
- db_list.map! do |version|
1093
- ["up", version, "********** NO FILE **********"]
1138
+ private
1139
+ def move(direction, steps)
1140
+ migrator = Migrator.new(direction, migrations)
1141
+
1142
+ if current_version != 0 && !migrator.current_migration
1143
+ raise UnknownMigrationVersionError.new(current_version)
1094
1144
  end
1095
1145
 
1096
- (db_list + file_list).sort_by { |_, version, _| version }
1097
- end
1146
+ start_index =
1147
+ if current_version == 0
1148
+ 0
1149
+ else
1150
+ migrator.migrations.index(migrator.current_migration)
1151
+ end
1098
1152
 
1099
- def migration_files(paths)
1100
- Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
1153
+ finish = migrator.migrations[start_index + steps]
1154
+ version = finish ? finish.version : 0
1155
+ send(direction, version)
1101
1156
  end
1157
+ end
1102
1158
 
1103
- private
1159
+ class Migrator # :nodoc:
1160
+ class << self
1161
+ attr_accessor :migrations_paths
1104
1162
 
1105
- def move(direction, migrations_paths, steps)
1106
- migrator = new(direction, migrations(migrations_paths))
1107
- start_index = migrator.migrations.index(migrator.current_migration)
1163
+ def migrations_path=(path)
1164
+ ActiveSupport::Deprecation.warn \
1165
+ "ActiveRecord::Migrator.migrations_paths= is now deprecated and will be removed in Rails 6.0." \
1166
+ "You can set the `migrations_paths` on the `connection` instead through the `database.yml`."
1167
+ self.migrations_paths = [path]
1168
+ end
1108
1169
 
1109
- if start_index
1110
- finish = migrator.migrations[start_index + steps]
1111
- version = finish ? finish.version : 0
1112
- send(direction, migrations_paths, version)
1113
- end
1170
+ # For cases where a table doesn't exist like loading from schema cache
1171
+ def current_version
1172
+ MigrationContext.new(migrations_paths).current_version
1114
1173
  end
1115
1174
  end
1116
1175
 
1176
+ self.migrations_paths = ["db/migrate"]
1177
+
1117
1178
  def initialize(direction, migrations, target_version = nil)
1118
1179
  @direction = direction
1119
1180
  @target_version = target_version
@@ -1176,7 +1237,7 @@ module ActiveRecord
1176
1237
  end
1177
1238
 
1178
1239
  def load_migrated
1179
- @migrated_versions = Set.new(self.class.get_all_versions)
1240
+ @migrated_versions = Set.new(Base.connection.migration_context.get_all_versions)
1180
1241
  end
1181
1242
 
1182
1243
  private
@@ -1208,7 +1269,7 @@ module ActiveRecord
1208
1269
  # Stores the current environment in the database.
1209
1270
  def record_environment
1210
1271
  return if down?
1211
- ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment
1272
+ ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Base.connection.migration_context.current_environment
1212
1273
  end
1213
1274
 
1214
1275
  def ran?(migration)
@@ -1217,7 +1278,7 @@ module ActiveRecord
1217
1278
 
1218
1279
  # Return true if a valid version is not provided.
1219
1280
  def invalid_target?
1220
- !target && @target_version && @target_version > 0
1281
+ @target_version && @target_version != 0 && !target
1221
1282
  end
1222
1283
 
1223
1284
  def execute_migration_in_transaction(migration, direction)
@@ -1231,7 +1292,7 @@ module ActiveRecord
1231
1292
  record_version_state_after_migrating(migration.version)
1232
1293
  end
1233
1294
  rescue => e
1234
- msg = "An error has occurred, "
1295
+ msg = "An error has occurred, ".dup
1235
1296
  msg << "this and " if use_transaction?(migration)
1236
1297
  msg << "all later migrations canceled:\n\n#{e}"
1237
1298
  raise StandardError, msg, e.backtrace
@@ -1250,10 +1311,10 @@ module ActiveRecord
1250
1311
  end
1251
1312
 
1252
1313
  def validate(migrations)
1253
- name , = migrations.group_by(&:name).find { |_, v| v.length > 1 }
1314
+ name, = migrations.group_by(&:name).find { |_, v| v.length > 1 }
1254
1315
  raise DuplicateMigrationNameError.new(name) if name
1255
1316
 
1256
- version , = migrations.group_by(&:version).find { |_, v| v.length > 1 }
1317
+ version, = migrations.group_by(&:version).find { |_, v| v.length > 1 }
1257
1318
  raise DuplicateMigrationVersionError.new(version) if version
1258
1319
  end
1259
1320
 
@@ -1267,23 +1328,6 @@ module ActiveRecord
1267
1328
  end
1268
1329
  end
1269
1330
 
1270
- def self.last_stored_environment
1271
- return nil if current_version == 0
1272
- raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
1273
-
1274
- environment = ActiveRecord::InternalMetadata[:environment]
1275
- raise NoEnvironmentInSchemaError unless environment
1276
- environment
1277
- end
1278
-
1279
- def self.current_environment
1280
- ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
1281
- end
1282
-
1283
- def self.protected_environment?
1284
- ActiveRecord::Base.protected_environments.include?(last_stored_environment) if last_stored_environment
1285
- end
1286
-
1287
1331
  def up?
1288
1332
  @direction == :up
1289
1333
  end