activerecord 6.0.0.beta1 → 6.0.1.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 (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +529 -10
  3. data/README.rdoc +3 -1
  4. data/lib/active_record.rb +7 -1
  5. data/lib/active_record/association_relation.rb +15 -6
  6. data/lib/active_record/associations.rb +4 -3
  7. data/lib/active_record/associations/association.rb +27 -2
  8. data/lib/active_record/associations/builder/association.rb +14 -18
  9. data/lib/active_record/associations/builder/belongs_to.rb +5 -2
  10. data/lib/active_record/associations/builder/collection_association.rb +5 -15
  11. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -1
  12. data/lib/active_record/associations/builder/has_many.rb +2 -0
  13. data/lib/active_record/associations/builder/has_one.rb +35 -1
  14. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  15. data/lib/active_record/associations/collection_association.rb +5 -6
  16. data/lib/active_record/associations/collection_proxy.rb +13 -42
  17. data/lib/active_record/associations/has_many_association.rb +1 -9
  18. data/lib/active_record/associations/has_many_through_association.rb +4 -11
  19. data/lib/active_record/associations/join_dependency.rb +14 -9
  20. data/lib/active_record/associations/join_dependency/join_association.rb +21 -7
  21. data/lib/active_record/associations/preloader.rb +12 -7
  22. data/lib/active_record/associations/preloader/association.rb +37 -34
  23. data/lib/active_record/associations/preloader/through_association.rb +48 -39
  24. data/lib/active_record/attribute_methods.rb +3 -53
  25. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
  26. data/lib/active_record/attribute_methods/dirty.rb +47 -14
  27. data/lib/active_record/attribute_methods/primary_key.rb +7 -15
  28. data/lib/active_record/attribute_methods/query.rb +2 -3
  29. data/lib/active_record/attribute_methods/read.rb +3 -9
  30. data/lib/active_record/attribute_methods/write.rb +6 -12
  31. data/lib/active_record/attributes.rb +13 -0
  32. data/lib/active_record/autosave_association.rb +21 -7
  33. data/lib/active_record/base.rb +0 -1
  34. data/lib/active_record/callbacks.rb +3 -3
  35. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +134 -23
  36. data/lib/active_record/connection_adapters/abstract/database_limits.rb +8 -4
  37. data/lib/active_record/connection_adapters/abstract/database_statements.rb +105 -70
  38. data/lib/active_record/connection_adapters/abstract/query_cache.rb +12 -5
  39. data/lib/active_record/connection_adapters/abstract/quoting.rb +63 -6
  40. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +5 -2
  41. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +51 -40
  42. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
  43. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +95 -30
  44. data/lib/active_record/connection_adapters/abstract/transaction.rb +17 -6
  45. data/lib/active_record/connection_adapters/abstract_adapter.rb +115 -35
  46. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +106 -138
  47. data/lib/active_record/connection_adapters/column.rb +17 -13
  48. data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
  49. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +3 -3
  50. data/lib/active_record/connection_adapters/mysql/database_statements.rb +48 -8
  51. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  52. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  53. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  54. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +66 -5
  55. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  56. data/lib/active_record/connection_adapters/mysql2_adapter.rb +18 -5
  57. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -30
  58. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +8 -2
  59. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  60. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  61. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
  62. data/lib/active_record/connection_adapters/postgresql/quoting.rb +40 -3
  63. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +36 -0
  64. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +98 -89
  65. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +47 -63
  66. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +23 -27
  67. data/lib/active_record/connection_adapters/postgresql_adapter.rb +95 -24
  68. data/lib/active_record/connection_adapters/schema_cache.rb +32 -14
  69. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  70. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  71. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -2
  72. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +28 -2
  73. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +73 -118
  74. data/lib/active_record/connection_handling.rb +40 -17
  75. data/lib/active_record/core.rb +35 -24
  76. data/lib/active_record/database_configurations.rb +99 -50
  77. data/lib/active_record/database_configurations/hash_config.rb +11 -11
  78. data/lib/active_record/database_configurations/url_config.rb +21 -16
  79. data/lib/active_record/dynamic_matchers.rb +1 -1
  80. data/lib/active_record/enum.rb +15 -0
  81. data/lib/active_record/errors.rb +18 -13
  82. data/lib/active_record/fixtures.rb +11 -6
  83. data/lib/active_record/gem_version.rb +2 -2
  84. data/lib/active_record/inheritance.rb +1 -1
  85. data/lib/active_record/insert_all.rb +179 -0
  86. data/lib/active_record/integration.rb +13 -1
  87. data/lib/active_record/internal_metadata.rb +5 -1
  88. data/lib/active_record/locking/optimistic.rb +3 -4
  89. data/lib/active_record/log_subscriber.rb +1 -1
  90. data/lib/active_record/middleware/database_selector.rb +75 -0
  91. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  92. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  93. data/lib/active_record/migration.rb +62 -44
  94. data/lib/active_record/migration/command_recorder.rb +28 -14
  95. data/lib/active_record/migration/compatibility.rb +72 -63
  96. data/lib/active_record/model_schema.rb +3 -0
  97. data/lib/active_record/persistence.rb +212 -19
  98. data/lib/active_record/querying.rb +18 -14
  99. data/lib/active_record/railtie.rb +9 -1
  100. data/lib/active_record/railties/collection_cache_association_loading.rb +3 -3
  101. data/lib/active_record/railties/databases.rake +124 -25
  102. data/lib/active_record/reflection.rb +18 -32
  103. data/lib/active_record/relation.rb +185 -35
  104. data/lib/active_record/relation/calculations.rb +40 -44
  105. data/lib/active_record/relation/delegation.rb +23 -31
  106. data/lib/active_record/relation/finder_methods.rb +23 -14
  107. data/lib/active_record/relation/merger.rb +11 -16
  108. data/lib/active_record/relation/query_attribute.rb +5 -3
  109. data/lib/active_record/relation/query_methods.rb +230 -69
  110. data/lib/active_record/relation/spawn_methods.rb +1 -1
  111. data/lib/active_record/relation/where_clause.rb +10 -10
  112. data/lib/active_record/sanitization.rb +33 -4
  113. data/lib/active_record/schema.rb +1 -1
  114. data/lib/active_record/schema_dumper.rb +10 -1
  115. data/lib/active_record/schema_migration.rb +1 -1
  116. data/lib/active_record/scoping.rb +6 -7
  117. data/lib/active_record/scoping/default.rb +7 -15
  118. data/lib/active_record/scoping/named.rb +10 -2
  119. data/lib/active_record/statement_cache.rb +2 -2
  120. data/lib/active_record/store.rb +48 -0
  121. data/lib/active_record/table_metadata.rb +9 -13
  122. data/lib/active_record/tasks/database_tasks.rb +109 -6
  123. data/lib/active_record/tasks/mysql_database_tasks.rb +3 -1
  124. data/lib/active_record/test_databases.rb +1 -16
  125. data/lib/active_record/test_fixtures.rb +2 -2
  126. data/lib/active_record/timestamp.rb +35 -19
  127. data/lib/active_record/touch_later.rb +4 -2
  128. data/lib/active_record/transactions.rb +56 -46
  129. data/lib/active_record/type_caster/connection.rb +16 -10
  130. data/lib/active_record/validations.rb +1 -0
  131. data/lib/active_record/validations/uniqueness.rb +4 -4
  132. data/lib/arel.rb +18 -4
  133. data/lib/arel/insert_manager.rb +3 -3
  134. data/lib/arel/nodes.rb +2 -1
  135. data/lib/arel/nodes/and.rb +1 -1
  136. data/lib/arel/nodes/case.rb +1 -1
  137. data/lib/arel/nodes/comment.rb +29 -0
  138. data/lib/arel/nodes/select_core.rb +16 -12
  139. data/lib/arel/nodes/unary.rb +1 -0
  140. data/lib/arel/nodes/values_list.rb +2 -17
  141. data/lib/arel/select_manager.rb +10 -10
  142. data/lib/arel/visitors/depth_first.rb +7 -2
  143. data/lib/arel/visitors/dot.rb +7 -2
  144. data/lib/arel/visitors/ibm_db.rb +13 -0
  145. data/lib/arel/visitors/informix.rb +6 -0
  146. data/lib/arel/visitors/mssql.rb +15 -1
  147. data/lib/arel/visitors/oracle12.rb +4 -5
  148. data/lib/arel/visitors/postgresql.rb +4 -10
  149. data/lib/arel/visitors/to_sql.rb +107 -131
  150. data/lib/arel/visitors/visitor.rb +9 -5
  151. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -1
  152. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  153. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  154. data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
  155. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  156. metadata +19 -12
  157. data/lib/active_record/collection_cache_key.rb +0 -53
  158. data/lib/arel/nodes/values.rb +0 -16
@@ -2,18 +2,23 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module Querying
5
- delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :none?, :one?, to: :all
6
- delegate :second, :second!, :third, :third!, :fourth, :fourth!, :fifth, :fifth!, :forty_two, :forty_two!, :third_to_last, :third_to_last!, :second_to_last, :second_to_last!, to: :all
7
- delegate :first_or_create, :first_or_create!, :first_or_initialize, to: :all
8
- delegate :find_or_create_by, :find_or_create_by!, :create_or_find_by, :create_or_find_by!, :find_or_initialize_by, to: :all
9
- delegate :find_by, :find_by!, to: :all
10
- delegate :destroy_all, :delete_all, :update_all, to: :all
11
- delegate :find_each, :find_in_batches, :in_batches, to: :all
12
- delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
13
- :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly, :extending,
14
- :having, :create_with, :distinct, :references, :none, :unscope, :merge, to: :all
15
- delegate :count, :average, :minimum, :maximum, :sum, :calculate, to: :all
16
- delegate :pluck, :pick, :ids, to: :all
5
+ QUERYING_METHODS = [
6
+ :find, :find_by, :find_by!, :take, :take!, :first, :first!, :last, :last!,
7
+ :second, :second!, :third, :third!, :fourth, :fourth!, :fifth, :fifth!,
8
+ :forty_two, :forty_two!, :third_to_last, :third_to_last!, :second_to_last, :second_to_last!,
9
+ :exists?, :any?, :many?, :none?, :one?,
10
+ :first_or_create, :first_or_create!, :first_or_initialize,
11
+ :find_or_create_by, :find_or_create_by!, :find_or_initialize_by,
12
+ :create_or_find_by, :create_or_find_by!,
13
+ :destroy_all, :delete_all, :update_all, :touch_all, :destroy_by, :delete_by,
14
+ :find_each, :find_in_batches, :in_batches,
15
+ :select, :reselect, :order, :reorder, :group, :limit, :offset, :joins, :left_joins, :left_outer_joins,
16
+ :where, :rewhere, :preload, :extract_associated, :eager_load, :includes, :from, :lock, :readonly, :extending, :or,
17
+ :having, :create_with, :distinct, :references, :none, :unscope, :optimizer_hints, :merge, :except, :only,
18
+ :count, :average, :minimum, :maximum, :sum, :calculate, :annotate,
19
+ :pluck, :pick, :ids
20
+ ].freeze # :nodoc:
21
+ delegate(*QUERYING_METHODS, to: :all)
17
22
 
18
23
  # Executes a custom SQL query against your database and returns all the results. The results will
19
24
  # be returned as an array, with the requested columns encapsulated as attributes of the model you call
@@ -40,8 +45,7 @@ module ActiveRecord
40
45
  def find_by_sql(sql, binds = [], preparable: nil, &block)
41
46
  result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
42
47
  column_types = result_set.column_types.dup
43
- cached_columns_hash = connection.schema_cache.columns_hash(table_name)
44
- cached_columns_hash.each_key { |k| column_types.delete k }
48
+ attribute_types.each_key { |k| column_types.delete k }
45
49
  message_bus = ActiveSupport::Notifications.instrumenter
46
50
 
47
51
  payload = {
@@ -88,6 +88,14 @@ module ActiveRecord
88
88
  end
89
89
  end
90
90
 
91
+ initializer "active_record.database_selector" do
92
+ if options = config.active_record.delete(:database_selector)
93
+ resolver = config.active_record.delete(:database_resolver)
94
+ operations = config.active_record.delete(:database_resolver_context)
95
+ config.app_middleware.use ActiveRecord::Middleware::DatabaseSelector, resolver, operations, options
96
+ end
97
+ end
98
+
91
99
  initializer "Check for cache versioning support" do
92
100
  config.after_initialize do |app|
93
101
  ActiveSupport.on_load(:active_record) do
@@ -126,7 +134,6 @@ end_error
126
134
 
127
135
  cache = YAML.load(File.read(filename))
128
136
  if cache.version == current_version
129
- connection.schema_cache = cache
130
137
  connection_pool.schema_cache = cache.dup
131
138
  else
132
139
  warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
@@ -189,6 +196,7 @@ end_error
189
196
  # and then establishes the connection.
190
197
  initializer "active_record.initialize_database" do
191
198
  ActiveSupport.on_load(:active_record) do
199
+ self.connection_handlers = { writing_role => ActiveRecord::Base.default_connection_handler }
192
200
  self.configurations = Rails.application.config.database_configuration
193
201
  establish_connection
194
202
  end
@@ -3,7 +3,7 @@
3
3
  module ActiveRecord
4
4
  module Railties # :nodoc:
5
5
  module CollectionCacheAssociationLoading #:nodoc:
6
- def setup(context, options, block)
6
+ def setup(context, options, as, block)
7
7
  @relation = relation_from_options(options)
8
8
 
9
9
  super
@@ -20,12 +20,12 @@ module ActiveRecord
20
20
  end
21
21
  end
22
22
 
23
- def collection_without_template
23
+ def collection_without_template(*)
24
24
  @relation.preload_associations(@collection) if @relation
25
25
  super
26
26
  end
27
27
 
28
- def collection_with_template
28
+ def collection_with_template(*)
29
29
  @relation.preload_associations(@collection) if @relation
30
30
  super
31
31
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "active_record"
4
4
 
5
+ databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
6
+
5
7
  db_namespace = namespace :db do
6
8
  desc "Set the environment value for the database"
7
9
  task "environment:set" => :load_config do
@@ -23,7 +25,7 @@ db_namespace = namespace :db do
23
25
  ActiveRecord::Tasks::DatabaseTasks.create_all
24
26
  end
25
27
 
26
- ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
28
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
27
29
  desc "Create #{spec_name} database for current environment"
28
30
  task spec_name => :load_config do
29
31
  db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
@@ -42,7 +44,7 @@ db_namespace = namespace :db do
42
44
  ActiveRecord::Tasks::DatabaseTasks.drop_all
43
45
  end
44
46
 
45
- ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
47
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
46
48
  desc "Drop #{spec_name} database for current environment"
47
49
  task spec_name => [:load_config, :check_protected_environments] do
48
50
  db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
@@ -66,6 +68,11 @@ db_namespace = namespace :db do
66
68
  end
67
69
  end
68
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
+
69
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."
70
77
  task purge: [:load_config, :check_protected_environments] do
71
78
  ActiveRecord::Tasks::DatabaseTasks.purge_current
@@ -73,7 +80,7 @@ db_namespace = namespace :db do
73
80
 
74
81
  desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
75
82
  task migrate: :load_config do
76
- ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
83
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
77
84
  ActiveRecord::Base.establish_connection(db_config.config)
78
85
  ActiveRecord::Tasks::DatabaseTasks.migrate
79
86
  end
@@ -96,7 +103,7 @@ db_namespace = namespace :db do
96
103
  end
97
104
 
98
105
  namespace :migrate do
99
- ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
106
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
100
107
  desc "Migrate #{spec_name} database for current environment"
101
108
  task spec_name => :load_config do
102
109
  db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
@@ -123,6 +130,8 @@ db_namespace = namespace :db do
123
130
 
124
131
  # desc 'Runs the "up" for a given migration VERSION.'
125
132
  task up: :load_config do
133
+ ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:up")
134
+
126
135
  raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
127
136
 
128
137
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
@@ -134,8 +143,29 @@ db_namespace = namespace :db do
134
143
  db_namespace["_dump"].invoke
135
144
  end
136
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
+
137
165
  # desc 'Runs the "down" for a given migration VERSION.'
138
166
  task down: :load_config do
167
+ ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:down")
168
+
139
169
  raise "VERSION is required - To go down one migration, use db:rollback" if !ENV["VERSION"] || ENV["VERSION"].empty?
140
170
 
141
171
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
@@ -147,16 +177,35 @@ db_namespace = namespace :db do
147
177
  db_namespace["_dump"].invoke
148
178
  end
149
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
+
150
199
  desc "Display status of migrations"
151
200
  task status: :load_config do
152
- ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
201
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
153
202
  ActiveRecord::Base.establish_connection(db_config.config)
154
203
  ActiveRecord::Tasks::DatabaseTasks.migrate_status
155
204
  end
156
205
  end
157
206
 
158
207
  namespace :status do
159
- ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
208
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
160
209
  desc "Display status of migrations for #{spec_name} database"
161
210
  task spec_name => :load_config do
162
211
  db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
@@ -203,7 +252,11 @@ db_namespace = namespace :db do
203
252
 
204
253
  # desc "Raises an error if there are pending migrations"
205
254
  task abort_if_pending_migrations: :load_config do
206
- 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
207
260
 
208
261
  if pending_migrations.any?
209
262
  puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
@@ -212,17 +265,74 @@ db_namespace = namespace :db do
212
265
  end
213
266
  abort %{Run `rails db:migrate` to update your database then try again.}
214
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
215
290
  end
216
291
 
217
292
  desc "Creates the database, loads the schema, and initializes with the seed data (use db:reset to also drop the database first)"
218
293
  task setup: ["db:schema:load_if_ruby", "db:structure:load_if_sql", :seed]
219
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
+
220
325
  desc "Loads the seed data from db/seeds.rb"
221
326
  task seed: :load_config do
222
327
  db_namespace["abort_if_pending_migrations"].invoke
223
328
  ActiveRecord::Tasks::DatabaseTasks.load_seed
224
329
  end
225
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
+
226
336
  namespace :fixtures do
227
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."
228
338
  task load: :load_config do
@@ -274,13 +384,9 @@ db_namespace = namespace :db do
274
384
  namespace :schema do
275
385
  desc "Creates a db/schema.rb file that is portable against any DB supported by Active Record"
276
386
  task dump: :load_config do
277
- require "active_record/schema_dumper"
278
- ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
279
- filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :ruby)
280
- File.open(filename, "w:utf-8") do |file|
281
- ActiveRecord::Base.establish_connection(db_config.config)
282
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
283
- end
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)
284
390
  end
285
391
 
286
392
  db_namespace["schema:dump"].reenable
@@ -298,7 +404,7 @@ db_namespace = namespace :db do
298
404
  namespace :cache do
299
405
  desc "Creates a db/schema_cache.yml file."
300
406
  task dump: :load_config do
301
- ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
407
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
302
408
  ActiveRecord::Base.establish_connection(db_config.config)
303
409
  filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.spec_name)
304
410
  ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(
@@ -310,7 +416,7 @@ db_namespace = namespace :db do
310
416
 
311
417
  desc "Clears a db/schema_cache.yml file."
312
418
  task clear: :load_config do
313
- ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
419
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
314
420
  filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.spec_name)
315
421
  rm_f filename, verbose: false
316
422
  end
@@ -321,16 +427,9 @@ db_namespace = namespace :db do
321
427
  namespace :structure do
322
428
  desc "Dumps the database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
323
429
  task dump: :load_config do
324
- ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
430
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
325
431
  ActiveRecord::Base.establish_connection(db_config.config)
326
- filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :sql)
327
- ActiveRecord::Tasks::DatabaseTasks.structure_dump(db_config.config, filename)
328
- if ActiveRecord::SchemaMigration.table_exists?
329
- File.open(filename, "a") do |f|
330
- f.puts ActiveRecord::Base.connection.dump_schema_information
331
- f.print "\n"
332
- end
333
- end
432
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, :sql, db_config.spec_name)
334
433
  end
335
434
 
336
435
  db_namespace["structure:dump"].reenable
@@ -21,12 +21,12 @@ module ActiveRecord
21
21
 
22
22
  def add_reflection(ar, name, reflection)
23
23
  ar.clear_reflections_cache
24
- name = name.to_s
24
+ name = -name.to_s
25
25
  ar._reflections = ar._reflections.except(name).merge!(name => reflection)
26
26
  end
27
27
 
28
28
  def add_aggregate_reflection(ar, name, reflection)
29
- ar.aggregate_reflections = ar.aggregate_reflections.merge(name.to_s => reflection)
29
+ ar.aggregate_reflections = ar.aggregate_reflections.merge(-name.to_s => reflection)
30
30
  end
31
31
 
32
32
  private
@@ -178,28 +178,24 @@ module ActiveRecord
178
178
  scope ? [scope] : []
179
179
  end
180
180
 
181
- def build_join_constraint(table, foreign_table)
182
- key = join_keys.key
183
- foreign_key = join_keys.foreign_key
184
-
185
- constraint = table[key].eq(foreign_table[foreign_key])
186
-
187
- if klass.finder_needs_type_condition?
188
- table.create_and([constraint, klass.send(:type_condition, table)])
189
- else
190
- constraint
191
- end
192
- end
193
-
194
- def join_scope(table, foreign_klass)
181
+ def join_scope(table, foreign_table, foreign_klass)
195
182
  predicate_builder = predicate_builder(table)
196
183
  scope_chain_items = join_scopes(table, predicate_builder)
197
184
  klass_scope = klass_join_scope(table, predicate_builder)
198
185
 
186
+ key = join_keys.key
187
+ foreign_key = join_keys.foreign_key
188
+
189
+ klass_scope.where!(table[key].eq(foreign_table[foreign_key]))
190
+
199
191
  if type
200
192
  klass_scope.where!(type => foreign_klass.polymorphic_name)
201
193
  end
202
194
 
195
+ if klass.finder_needs_type_condition?
196
+ klass_scope.where!(klass.send(:type_condition, table))
197
+ end
198
+
203
199
  scope_chain_items.inject(klass_scope, &:merge!)
204
200
  end
205
201
 
@@ -481,7 +477,7 @@ module ActiveRecord
481
477
  def check_preloadable!
482
478
  return unless scope
483
479
 
484
- if scope.arity > 0
480
+ unless scope.arity == 0
485
481
  raise ArgumentError, <<-MSG.squish
486
482
  The association scope '#{name}' is instance dependent (the scope
487
483
  block takes an argument). Preloading instance dependent scopes is
@@ -612,21 +608,9 @@ module ActiveRecord
612
608
 
613
609
  # returns either +nil+ or the inverse association name that it finds.
614
610
  def automatic_inverse_of
615
- return unless can_find_inverse_of_automatically?(self)
611
+ if can_find_inverse_of_automatically?(self)
612
+ inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_record.name.demodulize).to_sym
616
613
 
617
- inverse_name_candidates =
618
- if options[:as]
619
- [options[:as]]
620
- else
621
- active_record_name = active_record.name.demodulize
622
- [active_record_name, ActiveSupport::Inflector.pluralize(active_record_name)]
623
- end
624
-
625
- inverse_name_candidates.map! do |candidate|
626
- ActiveSupport::Inflector.underscore(candidate).to_sym
627
- end
628
-
629
- inverse_name_candidates.detect do |inverse_name|
630
614
  begin
631
615
  reflection = klass._reflect_on_association(inverse_name)
632
616
  rescue NameError
@@ -635,7 +619,9 @@ module ActiveRecord
635
619
  reflection = false
636
620
  end
637
621
 
638
- valid_inverse_reflection?(reflection)
622
+ if valid_inverse_reflection?(reflection)
623
+ return inverse_name
624
+ end
639
625
  end
640
626
  end
641
627