activerecord 5.2.6 → 6.0.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.

Files changed (268) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +609 -622
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +4 -2
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +4 -2
  7. data/lib/active_record/associations/association.rb +52 -19
  8. data/lib/active_record/associations/association_scope.rb +4 -6
  9. data/lib/active_record/associations/belongs_to_association.rb +36 -42
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
  11. data/lib/active_record/associations/builder/association.rb +14 -18
  12. data/lib/active_record/associations/builder/belongs_to.rb +19 -52
  13. data/lib/active_record/associations/builder/collection_association.rb +3 -13
  14. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
  15. data/lib/active_record/associations/builder/has_many.rb +2 -0
  16. data/lib/active_record/associations/builder/has_one.rb +35 -1
  17. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  18. data/lib/active_record/associations/collection_association.rb +6 -21
  19. data/lib/active_record/associations/collection_proxy.rb +12 -15
  20. data/lib/active_record/associations/foreign_association.rb +7 -0
  21. data/lib/active_record/associations/has_many_association.rb +2 -10
  22. data/lib/active_record/associations/has_many_through_association.rb +14 -14
  23. data/lib/active_record/associations/has_one_association.rb +28 -30
  24. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  25. data/lib/active_record/associations/join_dependency/join_association.rb +9 -10
  26. data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
  27. data/lib/active_record/associations/join_dependency.rb +24 -28
  28. data/lib/active_record/associations/preloader/association.rb +38 -36
  29. data/lib/active_record/associations/preloader/through_association.rb +48 -39
  30. data/lib/active_record/associations/preloader.rb +40 -32
  31. data/lib/active_record/associations/singular_association.rb +2 -16
  32. data/lib/active_record/associations.rb +19 -14
  33. data/lib/active_record/attribute_assignment.rb +7 -10
  34. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
  35. data/lib/active_record/attribute_methods/dirty.rb +111 -40
  36. data/lib/active_record/attribute_methods/primary_key.rb +15 -22
  37. data/lib/active_record/attribute_methods/query.rb +2 -3
  38. data/lib/active_record/attribute_methods/read.rb +15 -53
  39. data/lib/active_record/attribute_methods/serialization.rb +1 -1
  40. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
  41. data/lib/active_record/attribute_methods/write.rb +17 -24
  42. data/lib/active_record/attribute_methods.rb +28 -100
  43. data/lib/active_record/attributes.rb +13 -0
  44. data/lib/active_record/autosave_association.rb +5 -9
  45. data/lib/active_record/base.rb +2 -3
  46. data/lib/active_record/callbacks.rb +5 -19
  47. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +94 -16
  48. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
  49. data/lib/active_record/connection_adapters/abstract/database_statements.rb +95 -123
  50. data/lib/active_record/connection_adapters/abstract/query_cache.rb +17 -8
  51. data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
  52. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +19 -12
  53. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +76 -48
  54. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
  55. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +132 -53
  56. data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
  57. data/lib/active_record/connection_adapters/abstract_adapter.rb +180 -47
  58. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +128 -194
  59. data/lib/active_record/connection_adapters/column.rb +17 -13
  60. data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
  61. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
  62. data/lib/active_record/connection_adapters/mysql/database_statements.rb +73 -13
  63. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  64. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
  65. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  66. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  67. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +129 -13
  68. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -9
  70. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
  71. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -1
  72. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  73. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  74. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
  75. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
  76. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  77. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
  78. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  79. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  80. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
  81. data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
  82. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -1
  83. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  84. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +55 -53
  85. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
  86. data/lib/active_record/connection_adapters/postgresql_adapter.rb +160 -74
  87. data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
  88. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  89. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  90. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -6
  91. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
  92. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +125 -141
  93. data/lib/active_record/connection_handling.rb +149 -27
  94. data/lib/active_record/core.rb +100 -60
  95. data/lib/active_record/counter_cache.rb +4 -29
  96. data/lib/active_record/database_configurations/database_config.rb +37 -0
  97. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  98. data/lib/active_record/database_configurations/url_config.rb +79 -0
  99. data/lib/active_record/database_configurations.rb +233 -0
  100. data/lib/active_record/dynamic_matchers.rb +1 -1
  101. data/lib/active_record/enum.rb +37 -7
  102. data/lib/active_record/errors.rb +15 -7
  103. data/lib/active_record/explain.rb +1 -1
  104. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  105. data/lib/active_record/fixture_set/render_context.rb +17 -0
  106. data/lib/active_record/fixture_set/table_row.rb +153 -0
  107. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  108. data/lib/active_record/fixtures.rb +145 -472
  109. data/lib/active_record/gem_version.rb +3 -3
  110. data/lib/active_record/inheritance.rb +13 -3
  111. data/lib/active_record/insert_all.rb +179 -0
  112. data/lib/active_record/integration.rb +68 -16
  113. data/lib/active_record/internal_metadata.rb +10 -2
  114. data/lib/active_record/locking/optimistic.rb +5 -6
  115. data/lib/active_record/locking/pessimistic.rb +3 -3
  116. data/lib/active_record/log_subscriber.rb +7 -26
  117. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  118. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  119. data/lib/active_record/middleware/database_selector.rb +75 -0
  120. data/lib/active_record/migration/command_recorder.rb +50 -6
  121. data/lib/active_record/migration/compatibility.rb +76 -49
  122. data/lib/active_record/migration.rb +100 -81
  123. data/lib/active_record/model_schema.rb +30 -9
  124. data/lib/active_record/nested_attributes.rb +2 -2
  125. data/lib/active_record/no_touching.rb +7 -0
  126. data/lib/active_record/persistence.rb +228 -24
  127. data/lib/active_record/query_cache.rb +11 -4
  128. data/lib/active_record/querying.rb +32 -20
  129. data/lib/active_record/railtie.rb +80 -43
  130. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  131. data/lib/active_record/railties/controller_runtime.rb +30 -35
  132. data/lib/active_record/railties/databases.rake +196 -46
  133. data/lib/active_record/reflection.rb +32 -30
  134. data/lib/active_record/relation/batches.rb +13 -10
  135. data/lib/active_record/relation/calculations.rb +53 -47
  136. data/lib/active_record/relation/delegation.rb +26 -43
  137. data/lib/active_record/relation/finder_methods.rb +13 -26
  138. data/lib/active_record/relation/merger.rb +11 -20
  139. data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
  140. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  141. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  142. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  143. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  144. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  145. data/lib/active_record/relation/predicate_builder.rb +4 -6
  146. data/lib/active_record/relation/query_attribute.rb +13 -8
  147. data/lib/active_record/relation/query_methods.rb +189 -63
  148. data/lib/active_record/relation/spawn_methods.rb +1 -1
  149. data/lib/active_record/relation/where_clause.rb +14 -10
  150. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  151. data/lib/active_record/relation.rb +310 -80
  152. data/lib/active_record/result.rb +30 -11
  153. data/lib/active_record/sanitization.rb +32 -40
  154. data/lib/active_record/schema.rb +2 -11
  155. data/lib/active_record/schema_dumper.rb +22 -7
  156. data/lib/active_record/schema_migration.rb +5 -1
  157. data/lib/active_record/scoping/default.rb +4 -5
  158. data/lib/active_record/scoping/named.rb +19 -15
  159. data/lib/active_record/scoping.rb +8 -8
  160. data/lib/active_record/statement_cache.rb +30 -3
  161. data/lib/active_record/store.rb +87 -8
  162. data/lib/active_record/table_metadata.rb +10 -17
  163. data/lib/active_record/tasks/database_tasks.rb +194 -25
  164. data/lib/active_record/tasks/mysql_database_tasks.rb +5 -5
  165. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
  166. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
  167. data/lib/active_record/test_databases.rb +23 -0
  168. data/lib/active_record/test_fixtures.rb +224 -0
  169. data/lib/active_record/timestamp.rb +39 -25
  170. data/lib/active_record/touch_later.rb +4 -2
  171. data/lib/active_record/transactions.rb +57 -66
  172. data/lib/active_record/translation.rb +1 -1
  173. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  174. data/lib/active_record/type.rb +3 -4
  175. data/lib/active_record/type_caster/connection.rb +15 -14
  176. data/lib/active_record/type_caster/map.rb +1 -4
  177. data/lib/active_record/validations/uniqueness.rb +15 -27
  178. data/lib/active_record/validations.rb +1 -0
  179. data/lib/active_record.rb +9 -2
  180. data/lib/arel/alias_predication.rb +9 -0
  181. data/lib/arel/attributes/attribute.rb +37 -0
  182. data/lib/arel/attributes.rb +22 -0
  183. data/lib/arel/collectors/bind.rb +24 -0
  184. data/lib/arel/collectors/composite.rb +31 -0
  185. data/lib/arel/collectors/plain_string.rb +20 -0
  186. data/lib/arel/collectors/sql_string.rb +20 -0
  187. data/lib/arel/collectors/substitute_binds.rb +28 -0
  188. data/lib/arel/crud.rb +42 -0
  189. data/lib/arel/delete_manager.rb +18 -0
  190. data/lib/arel/errors.rb +9 -0
  191. data/lib/arel/expressions.rb +29 -0
  192. data/lib/arel/factory_methods.rb +49 -0
  193. data/lib/arel/insert_manager.rb +49 -0
  194. data/lib/arel/math.rb +45 -0
  195. data/lib/arel/nodes/and.rb +32 -0
  196. data/lib/arel/nodes/ascending.rb +23 -0
  197. data/lib/arel/nodes/binary.rb +52 -0
  198. data/lib/arel/nodes/bind_param.rb +36 -0
  199. data/lib/arel/nodes/case.rb +55 -0
  200. data/lib/arel/nodes/casted.rb +50 -0
  201. data/lib/arel/nodes/comment.rb +29 -0
  202. data/lib/arel/nodes/count.rb +12 -0
  203. data/lib/arel/nodes/delete_statement.rb +45 -0
  204. data/lib/arel/nodes/descending.rb +23 -0
  205. data/lib/arel/nodes/equality.rb +18 -0
  206. data/lib/arel/nodes/extract.rb +24 -0
  207. data/lib/arel/nodes/false.rb +16 -0
  208. data/lib/arel/nodes/full_outer_join.rb +8 -0
  209. data/lib/arel/nodes/function.rb +44 -0
  210. data/lib/arel/nodes/grouping.rb +8 -0
  211. data/lib/arel/nodes/in.rb +8 -0
  212. data/lib/arel/nodes/infix_operation.rb +80 -0
  213. data/lib/arel/nodes/inner_join.rb +8 -0
  214. data/lib/arel/nodes/insert_statement.rb +37 -0
  215. data/lib/arel/nodes/join_source.rb +20 -0
  216. data/lib/arel/nodes/matches.rb +18 -0
  217. data/lib/arel/nodes/named_function.rb +23 -0
  218. data/lib/arel/nodes/node.rb +50 -0
  219. data/lib/arel/nodes/node_expression.rb +13 -0
  220. data/lib/arel/nodes/outer_join.rb +8 -0
  221. data/lib/arel/nodes/over.rb +15 -0
  222. data/lib/arel/nodes/regexp.rb +16 -0
  223. data/lib/arel/nodes/right_outer_join.rb +8 -0
  224. data/lib/arel/nodes/select_core.rb +67 -0
  225. data/lib/arel/nodes/select_statement.rb +41 -0
  226. data/lib/arel/nodes/sql_literal.rb +16 -0
  227. data/lib/arel/nodes/string_join.rb +11 -0
  228. data/lib/arel/nodes/table_alias.rb +27 -0
  229. data/lib/arel/nodes/terminal.rb +16 -0
  230. data/lib/arel/nodes/true.rb +16 -0
  231. data/lib/arel/nodes/unary.rb +45 -0
  232. data/lib/arel/nodes/unary_operation.rb +20 -0
  233. data/lib/arel/nodes/unqualified_column.rb +22 -0
  234. data/lib/arel/nodes/update_statement.rb +41 -0
  235. data/lib/arel/nodes/values_list.rb +9 -0
  236. data/lib/arel/nodes/window.rb +126 -0
  237. data/lib/arel/nodes/with.rb +11 -0
  238. data/lib/arel/nodes.rb +68 -0
  239. data/lib/arel/order_predications.rb +13 -0
  240. data/lib/arel/predications.rb +257 -0
  241. data/lib/arel/select_manager.rb +271 -0
  242. data/lib/arel/table.rb +110 -0
  243. data/lib/arel/tree_manager.rb +72 -0
  244. data/lib/arel/update_manager.rb +34 -0
  245. data/lib/arel/visitors/depth_first.rb +204 -0
  246. data/lib/arel/visitors/dot.rb +297 -0
  247. data/lib/arel/visitors/ibm_db.rb +34 -0
  248. data/lib/arel/visitors/informix.rb +62 -0
  249. data/lib/arel/visitors/mssql.rb +157 -0
  250. data/lib/arel/visitors/mysql.rb +83 -0
  251. data/lib/arel/visitors/oracle.rb +159 -0
  252. data/lib/arel/visitors/oracle12.rb +66 -0
  253. data/lib/arel/visitors/postgresql.rb +110 -0
  254. data/lib/arel/visitors/sqlite.rb +39 -0
  255. data/lib/arel/visitors/to_sql.rb +889 -0
  256. data/lib/arel/visitors/visitor.rb +46 -0
  257. data/lib/arel/visitors/where_sql.rb +23 -0
  258. data/lib/arel/visitors.rb +20 -0
  259. data/lib/arel/window_predications.rb +9 -0
  260. data/lib/arel.rb +51 -0
  261. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  262. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  263. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  264. data/lib/rails/generators/active_record/migration.rb +14 -1
  265. data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
  266. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  267. metadata +108 -26
  268. data/lib/active_record/collection_cache_key.rb +0 -53
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "active_record"
4
4
 
5
+ databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
6
+
5
7
  db_namespace = namespace :db do
6
8
  desc "Set the environment value for the database"
7
9
  task "environment:set" => :load_config do
@@ -22,6 +24,14 @@ db_namespace = namespace :db do
22
24
  task all: :load_config do
23
25
  ActiveRecord::Tasks::DatabaseTasks.create_all
24
26
  end
27
+
28
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
29
+ desc "Create #{spec_name} database for current environment"
30
+ task spec_name => :load_config do
31
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
32
+ ActiveRecord::Tasks::DatabaseTasks.create(db_config.config)
33
+ end
34
+ end
25
35
  end
26
36
 
27
37
  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 +43,14 @@ db_namespace = namespace :db do
33
43
  task all: [:load_config, :check_protected_environments] do
34
44
  ActiveRecord::Tasks::DatabaseTasks.drop_all
35
45
  end
46
+
47
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
48
+ desc "Drop #{spec_name} database for current environment"
49
+ task spec_name => [:load_config, :check_protected_environments] do
50
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
51
+ ActiveRecord::Tasks::DatabaseTasks.drop(db_config.config)
52
+ end
53
+ end
36
54
  end
37
55
 
38
56
  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."
@@ -50,6 +68,11 @@ db_namespace = namespace :db do
50
68
  end
51
69
  end
52
70
 
71
+ # desc "Truncates tables of each database for current environment"
72
+ task truncate_all: [:load_config, :check_protected_environments] do
73
+ ActiveRecord::Tasks::DatabaseTasks.truncate_all
74
+ end
75
+
53
76
  # desc "Empty the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:purge:all to purge all databases in the config). Without RAILS_ENV it defaults to purging the development and test databases."
54
77
  task purge: [:load_config, :check_protected_environments] do
55
78
  ActiveRecord::Tasks::DatabaseTasks.purge_current
@@ -57,7 +80,10 @@ db_namespace = namespace :db do
57
80
 
58
81
  desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
59
82
  task migrate: :load_config do
60
- ActiveRecord::Tasks::DatabaseTasks.migrate
83
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
84
+ ActiveRecord::Base.establish_connection(db_config.config)
85
+ ActiveRecord::Tasks::DatabaseTasks.migrate
86
+ end
61
87
  db_namespace["_dump"].invoke
62
88
  end
63
89
 
@@ -77,6 +103,15 @@ db_namespace = namespace :db do
77
103
  end
78
104
 
79
105
  namespace :migrate do
106
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
107
+ desc "Migrate #{spec_name} database for current environment"
108
+ task spec_name => :load_config do
109
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
110
+ ActiveRecord::Base.establish_connection(db_config.config)
111
+ ActiveRecord::Tasks::DatabaseTasks.migrate
112
+ end
113
+ end
114
+
80
115
  # desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
81
116
  task redo: :load_config do
82
117
  raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
@@ -95,6 +130,8 @@ db_namespace = namespace :db do
95
130
 
96
131
  # desc 'Runs the "up" for a given migration VERSION.'
97
132
  task up: :load_config do
133
+ ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:up")
134
+
98
135
  raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
99
136
 
100
137
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
@@ -106,8 +143,29 @@ db_namespace = namespace :db do
106
143
  db_namespace["_dump"].invoke
107
144
  end
108
145
 
146
+ namespace :up do
147
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
148
+ task spec_name => :load_config do
149
+ raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
150
+
151
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
152
+
153
+ ActiveRecord::Base.establish_connection(db_config.config)
154
+ ActiveRecord::Tasks::DatabaseTasks.check_target_version
155
+ ActiveRecord::Base.connection.migration_context.run(
156
+ :up,
157
+ ActiveRecord::Tasks::DatabaseTasks.target_version
158
+ )
159
+
160
+ db_namespace["_dump"].invoke
161
+ end
162
+ end
163
+ end
164
+
109
165
  # desc 'Runs the "down" for a given migration VERSION.'
110
166
  task down: :load_config do
167
+ ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:down")
168
+
111
169
  raise "VERSION is required - To go down one migration, use db:rollback" if !ENV["VERSION"] || ENV["VERSION"].empty?
112
170
 
113
171
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
@@ -119,20 +177,42 @@ db_namespace = namespace :db do
119
177
  db_namespace["_dump"].invoke
120
178
  end
121
179
 
180
+ namespace :down do
181
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
182
+ task spec_name => :load_config do
183
+ raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
184
+
185
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
186
+
187
+ ActiveRecord::Base.establish_connection(db_config.config)
188
+ ActiveRecord::Tasks::DatabaseTasks.check_target_version
189
+ ActiveRecord::Base.connection.migration_context.run(
190
+ :down,
191
+ ActiveRecord::Tasks::DatabaseTasks.target_version
192
+ )
193
+
194
+ db_namespace["_dump"].invoke
195
+ end
196
+ end
197
+ end
198
+
122
199
  desc "Display status of migrations"
123
200
  task status: :load_config do
124
- unless ActiveRecord::SchemaMigration.table_exists?
125
- abort "Schema migrations table does not exist yet."
201
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
202
+ ActiveRecord::Base.establish_connection(db_config.config)
203
+ ActiveRecord::Tasks::DatabaseTasks.migrate_status
126
204
  end
205
+ end
127
206
 
128
- # output
129
- puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
130
- puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
131
- puts "-" * 50
132
- ActiveRecord::Base.connection.migration_context.migrations_status.each do |status, version, name|
133
- puts "#{status.center(8)} #{version.ljust(14)} #{name}"
207
+ namespace :status do
208
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
209
+ desc "Display status of migrations for #{spec_name} database"
210
+ task spec_name => :load_config do
211
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
212
+ ActiveRecord::Base.establish_connection(db_config.config)
213
+ ActiveRecord::Tasks::DatabaseTasks.migrate_status
214
+ end
134
215
  end
135
- puts
136
216
  end
137
217
  end
138
218
 
@@ -160,11 +240,9 @@ db_namespace = namespace :db do
160
240
 
161
241
  # desc "Retrieves the collation for the current environment's database"
162
242
  task collation: :load_config do
163
- begin
164
- puts ActiveRecord::Tasks::DatabaseTasks.collation_current
165
- rescue NoMethodError
166
- $stderr.puts "Sorry, your database adapter is not supported yet. Feel free to submit a patch."
167
- end
243
+ puts ActiveRecord::Tasks::DatabaseTasks.collation_current
244
+ rescue NoMethodError
245
+ $stderr.puts "Sorry, your database adapter is not supported yet. Feel free to submit a patch."
168
246
  end
169
247
 
170
248
  desc "Retrieves the current schema version number"
@@ -174,7 +252,11 @@ db_namespace = namespace :db do
174
252
 
175
253
  # desc "Raises an error if there are pending migrations"
176
254
  task abort_if_pending_migrations: :load_config do
177
- pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
255
+ pending_migrations = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).flat_map do |db_config|
256
+ ActiveRecord::Base.establish_connection(db_config.config)
257
+
258
+ ActiveRecord::Base.connection.migration_context.open.pending_migrations
259
+ end
178
260
 
179
261
  if pending_migrations.any?
180
262
  puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
@@ -183,17 +265,74 @@ db_namespace = namespace :db do
183
265
  end
184
266
  abort %{Run `rails db:migrate` to update your database then try again.}
185
267
  end
268
+ ensure
269
+ ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
270
+ end
271
+
272
+ namespace :abort_if_pending_migrations do
273
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
274
+ # desc "Raises an error if there are pending migrations for #{spec_name} database"
275
+ task spec_name => :load_config do
276
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
277
+ ActiveRecord::Base.establish_connection(db_config.config)
278
+
279
+ pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
280
+
281
+ if pending_migrations.any?
282
+ puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
283
+ pending_migrations.each do |pending_migration|
284
+ puts " %4d %s" % [pending_migration.version, pending_migration.name]
285
+ end
286
+ abort %{Run `rails db:migrate:#{spec_name}` to update your database then try again.}
287
+ end
288
+ end
289
+ end
186
290
  end
187
291
 
188
292
  desc "Creates the database, loads the schema, and initializes with the seed data (use db:reset to also drop the database first)"
189
293
  task setup: ["db:schema:load_if_ruby", "db:structure:load_if_sql", :seed]
190
294
 
295
+ desc "Runs setup if database does not exist, or runs migrations if it does"
296
+ task prepare: :load_config do
297
+ seed = false
298
+
299
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
300
+ ActiveRecord::Base.establish_connection(db_config.config)
301
+
302
+ # Skipped when no database
303
+ ActiveRecord::Tasks::DatabaseTasks.migrate
304
+ if ActiveRecord::Base.dump_schema_after_migration
305
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, ActiveRecord::Base.schema_format, db_config.spec_name)
306
+ end
307
+
308
+ rescue ActiveRecord::NoDatabaseError
309
+ ActiveRecord::Tasks::DatabaseTasks.create_current(db_config.env_name, db_config.spec_name)
310
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(
311
+ db_config.config,
312
+ ActiveRecord::Base.schema_format,
313
+ nil,
314
+ db_config.env_name,
315
+ db_config.spec_name
316
+ )
317
+
318
+ seed = true
319
+ end
320
+
321
+ ActiveRecord::Base.establish_connection
322
+ ActiveRecord::Tasks::DatabaseTasks.load_seed if seed
323
+ end
324
+
191
325
  desc "Loads the seed data from db/seeds.rb"
192
- task :seed do
326
+ task seed: :load_config do
193
327
  db_namespace["abort_if_pending_migrations"].invoke
194
328
  ActiveRecord::Tasks::DatabaseTasks.load_seed
195
329
  end
196
330
 
331
+ namespace :seed do
332
+ desc "Truncates tables of each database for current environment and loads the seeds"
333
+ task replant: [:load_config, :truncate_all, :seed]
334
+ end
335
+
197
336
  namespace :fixtures do
198
337
  desc "Loads fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
199
338
  task load: :load_config do
@@ -245,11 +384,11 @@ db_namespace = namespace :db do
245
384
  namespace :schema do
246
385
  desc "Creates a db/schema.rb file that is portable against any DB supported by Active Record"
247
386
  task dump: :load_config do
248
- require "active_record/schema_dumper"
249
- filename = ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema.rb")
250
- File.open(filename, "w:utf-8") do |file|
251
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
387
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
388
+ ActiveRecord::Base.establish_connection(db_config.config)
389
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, :ruby, db_config.spec_name)
252
390
  end
391
+
253
392
  db_namespace["schema:dump"].reenable
254
393
  end
255
394
 
@@ -265,33 +404,34 @@ db_namespace = namespace :db do
265
404
  namespace :cache do
266
405
  desc "Creates a db/schema_cache.yml file."
267
406
  task dump: :load_config do
268
- conn = ActiveRecord::Base.connection
269
- filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.yml")
270
- ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(conn, filename)
407
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
408
+ ActiveRecord::Base.establish_connection(db_config.config)
409
+ filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.spec_name)
410
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(
411
+ ActiveRecord::Base.connection,
412
+ filename,
413
+ )
414
+ end
271
415
  end
272
416
 
273
417
  desc "Clears a db/schema_cache.yml file."
274
418
  task clear: :load_config do
275
- filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.yml")
276
- rm_f filename, verbose: false
419
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
420
+ filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.spec_name)
421
+ rm_f filename, verbose: false
422
+ end
277
423
  end
278
424
  end
279
-
280
425
  end
281
426
 
282
427
  namespace :structure do
283
428
  desc "Dumps the database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
284
429
  task dump: :load_config do
285
- filename = ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql")
286
- current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
287
- ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename)
288
-
289
- if ActiveRecord::SchemaMigration.table_exists?
290
- File.open(filename, "a") do |f|
291
- f.puts ActiveRecord::Base.connection.dump_schema_information
292
- f.print "\n"
293
- end
430
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
431
+ ActiveRecord::Base.establish_connection(db_config.config)
432
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, :sql, db_config.spec_name)
294
433
  end
434
+
295
435
  db_namespace["structure:dump"].reenable
296
436
  end
297
437
 
@@ -318,25 +458,31 @@ db_namespace = namespace :db do
318
458
 
319
459
  # desc "Recreate the test database from an existent schema.rb file"
320
460
  task load_schema: %w(db:test:purge) do
321
- begin
322
- should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
323
- ActiveRecord::Schema.verbose = false
324
- ActiveRecord::Tasks::DatabaseTasks.load_schema ActiveRecord::Base.configurations["test"], :ruby, ENV["SCHEMA"], "test"
325
- ensure
326
- if should_reconnect
327
- ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[ActiveRecord::Tasks::DatabaseTasks.env])
328
- end
461
+ should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
462
+ ActiveRecord::Schema.verbose = false
463
+ ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
464
+ filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :ruby)
465
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config.config, :ruby, filename, "test")
466
+ end
467
+ ensure
468
+ if should_reconnect
469
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations.default_hash(ActiveRecord::Tasks::DatabaseTasks.env))
329
470
  end
330
471
  end
331
472
 
332
473
  # desc "Recreate the test database from an existent structure.sql file"
333
474
  task load_structure: %w(db:test:purge) do
334
- ActiveRecord::Tasks::DatabaseTasks.load_schema ActiveRecord::Base.configurations["test"], :sql, ENV["SCHEMA"], "test"
475
+ ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
476
+ filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :sql)
477
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config.config, :sql, filename, "test")
478
+ end
335
479
  end
336
480
 
337
481
  # desc "Empty the test database"
338
482
  task purge: %w(load_config check_protected_environments) do
339
- ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations["test"]
483
+ ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
484
+ ActiveRecord::Tasks::DatabaseTasks.purge(db_config.config)
485
+ end
340
486
  end
341
487
 
342
488
  # desc 'Load the test schema'
@@ -360,6 +506,10 @@ namespace :railties do
360
506
  if railtie.respond_to?(:paths) && (path = railtie.paths["db/migrate"].first)
361
507
  railties[railtie.railtie_name] = path
362
508
  end
509
+
510
+ unless ENV["MIGRATIONS_PATH"].blank?
511
+ railties[railtie.railtie_name] = railtie.root + ENV["MIGRATIONS_PATH"]
512
+ end
363
513
  end
364
514
 
365
515
  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
- def self.create(macro, name, scope, options, ar)
17
- klass = \
18
- case macro
19
- when :composed_of
20
- AggregateReflection
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
- reflection = klass.new(name, scope, options, ar)
32
- options[:through] ? ThroughReflection.new(reflection) : reflection
33
- end
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
- def self.add_reflection(ar, name, reflection)
36
- ar.clear_reflections_cache
37
- name = name.to_s
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
- def self.add_aggregate_reflection(ar, name, reflection)
42
- ar.aggregate_reflections = ar.aggregate_reflections.merge(name.to_s => reflection)
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
@@ -413,7 +417,7 @@ module ActiveRecord
413
417
  class AssociationReflection < MacroReflection #:nodoc:
414
418
  def compute_class(name)
415
419
  if polymorphic?
416
- raise ArgumentError, "Polymorphic association does not support to compute class."
420
+ raise ArgumentError, "Polymorphic associations do not support computing the class."
417
421
  end
418
422
  active_record.send(:compute_type, name)
419
423
  end
@@ -473,7 +477,7 @@ module ActiveRecord
473
477
  def check_preloadable!
474
478
  return unless scope
475
479
 
476
- if scope.arity > 0
480
+ unless scope.arity == 0
477
481
  raise ArgumentError, <<-MSG.squish
478
482
  The association scope '#{name}' is instance dependent (the scope
479
483
  block takes an argument). Preloading instance dependent scopes is
@@ -961,16 +965,14 @@ module ActiveRecord
961
965
  collect_join_reflections(seed + [self])
962
966
  end
963
967
 
964
- # TODO Change this to private once we've dropped Ruby 2.2 support.
965
- # Workaround for Ruby 2.2 "private attribute?" warning.
966
968
  protected
967
- attr_reader :delegate_reflection
968
-
969
969
  def actual_source_reflection # FIXME: this is a horrible name
970
970
  source_reflection.actual_source_reflection
971
971
  end
972
972
 
973
973
  private
974
+ attr_reader :delegate_reflection
975
+
974
976
  def collect_join_reflections(seed)
975
977
  a = source_reflection.add_as_source seed
976
978
  if options[:source_type]
@@ -251,25 +251,28 @@ module ActiveRecord
251
251
  end
252
252
  end
253
253
 
254
- attr = Relation::QueryAttribute.new(primary_key, primary_key_offset, klass.type_for_attribute(primary_key))
255
- batch_relation = relation.where(arel_attribute(primary_key).gt(Arel::Nodes::BindParam.new(attr)))
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
- attr = Relation::QueryAttribute.new(primary_key, start, klass.type_for_attribute(primary_key))
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