activerecord 6.1.7.2 → 7.0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1295 -1007
  3. data/README.rdoc +1 -1
  4. data/lib/active_record/aggregations.rb +1 -1
  5. data/lib/active_record/association_relation.rb +0 -10
  6. data/lib/active_record/associations/association.rb +33 -17
  7. data/lib/active_record/associations/association_scope.rb +1 -3
  8. data/lib/active_record/associations/belongs_to_association.rb +15 -4
  9. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  10. data/lib/active_record/associations/builder/association.rb +8 -2
  11. data/lib/active_record/associations/builder/belongs_to.rb +19 -6
  12. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  13. data/lib/active_record/associations/builder/has_many.rb +3 -2
  14. data/lib/active_record/associations/builder/has_one.rb +2 -1
  15. data/lib/active_record/associations/builder/singular_association.rb +2 -2
  16. data/lib/active_record/associations/collection_association.rb +19 -21
  17. data/lib/active_record/associations/collection_proxy.rb +10 -5
  18. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  19. data/lib/active_record/associations/has_many_association.rb +8 -5
  20. data/lib/active_record/associations/has_many_through_association.rb +2 -1
  21. data/lib/active_record/associations/has_one_association.rb +10 -7
  22. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  23. data/lib/active_record/associations/join_dependency.rb +23 -15
  24. data/lib/active_record/associations/preloader/association.rb +186 -52
  25. data/lib/active_record/associations/preloader/batch.rb +48 -0
  26. data/lib/active_record/associations/preloader/branch.rb +147 -0
  27. data/lib/active_record/associations/preloader/through_association.rb +49 -13
  28. data/lib/active_record/associations/preloader.rb +39 -113
  29. data/lib/active_record/associations/singular_association.rb +8 -2
  30. data/lib/active_record/associations/through_association.rb +3 -3
  31. data/lib/active_record/associations.rb +124 -95
  32. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  33. data/lib/active_record/attribute_assignment.rb +1 -1
  34. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
  35. data/lib/active_record/attribute_methods/dirty.rb +49 -16
  36. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  37. data/lib/active_record/attribute_methods/query.rb +2 -2
  38. data/lib/active_record/attribute_methods/read.rb +7 -5
  39. data/lib/active_record/attribute_methods/serialization.rb +57 -19
  40. data/lib/active_record/attribute_methods/time_zone_conversion.rb +8 -3
  41. data/lib/active_record/attribute_methods/write.rb +7 -10
  42. data/lib/active_record/attribute_methods.rb +14 -15
  43. data/lib/active_record/attributes.rb +24 -35
  44. data/lib/active_record/autosave_association.rb +8 -23
  45. data/lib/active_record/base.rb +19 -1
  46. data/lib/active_record/callbacks.rb +2 -2
  47. data/lib/active_record/coders/yaml_column.rb +4 -8
  48. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  49. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  50. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
  56. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
  57. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +38 -13
  58. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  59. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +80 -24
  60. data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
  61. data/lib/active_record/connection_adapters/abstract_adapter.rb +149 -74
  62. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +105 -81
  63. data/lib/active_record/connection_adapters/column.rb +4 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -24
  65. data/lib/active_record/connection_adapters/mysql/quoting.rb +37 -21
  66. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
  67. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +20 -1
  68. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
  69. data/lib/active_record/connection_adapters/pool_config.rb +7 -7
  70. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -1
  71. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -12
  72. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  73. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  74. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  75. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  76. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  77. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  78. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  79. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  80. data/lib/active_record/connection_adapters/postgresql/quoting.rb +71 -71
  81. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -0
  82. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
  83. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
  84. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
  85. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +37 -19
  86. data/lib/active_record/connection_adapters/postgresql_adapter.rb +206 -105
  87. data/lib/active_record/connection_adapters/schema_cache.rb +39 -38
  88. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
  89. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +28 -16
  90. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +17 -15
  91. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +96 -32
  92. data/lib/active_record/connection_adapters.rb +6 -5
  93. data/lib/active_record/connection_handling.rb +49 -55
  94. data/lib/active_record/core.rb +123 -148
  95. data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
  96. data/lib/active_record/database_configurations/database_config.rb +12 -9
  97. data/lib/active_record/database_configurations/hash_config.rb +63 -5
  98. data/lib/active_record/database_configurations/url_config.rb +2 -2
  99. data/lib/active_record/database_configurations.rb +15 -32
  100. data/lib/active_record/delegated_type.rb +53 -12
  101. data/lib/active_record/destroy_association_async_job.rb +1 -1
  102. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  103. data/lib/active_record/dynamic_matchers.rb +1 -1
  104. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  105. data/lib/active_record/encryption/cipher.rb +53 -0
  106. data/lib/active_record/encryption/config.rb +44 -0
  107. data/lib/active_record/encryption/configurable.rb +67 -0
  108. data/lib/active_record/encryption/context.rb +35 -0
  109. data/lib/active_record/encryption/contexts.rb +72 -0
  110. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  111. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  112. data/lib/active_record/encryption/encryptable_record.rb +206 -0
  113. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  114. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  115. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  116. data/lib/active_record/encryption/encryptor.rb +155 -0
  117. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  118. data/lib/active_record/encryption/errors.rb +15 -0
  119. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  120. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  121. data/lib/active_record/encryption/key.rb +28 -0
  122. data/lib/active_record/encryption/key_generator.rb +42 -0
  123. data/lib/active_record/encryption/key_provider.rb +46 -0
  124. data/lib/active_record/encryption/message.rb +33 -0
  125. data/lib/active_record/encryption/message_serializer.rb +90 -0
  126. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  127. data/lib/active_record/encryption/properties.rb +76 -0
  128. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  129. data/lib/active_record/encryption/scheme.rb +99 -0
  130. data/lib/active_record/encryption.rb +55 -0
  131. data/lib/active_record/enum.rb +50 -43
  132. data/lib/active_record/errors.rb +67 -4
  133. data/lib/active_record/explain_registry.rb +11 -6
  134. data/lib/active_record/fixture_set/file.rb +15 -1
  135. data/lib/active_record/fixture_set/table_row.rb +41 -6
  136. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  137. data/lib/active_record/fixtures.rb +20 -23
  138. data/lib/active_record/future_result.rb +139 -0
  139. data/lib/active_record/gem_version.rb +4 -4
  140. data/lib/active_record/inheritance.rb +55 -17
  141. data/lib/active_record/insert_all.rb +80 -14
  142. data/lib/active_record/integration.rb +4 -3
  143. data/lib/active_record/internal_metadata.rb +1 -5
  144. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  145. data/lib/active_record/locking/optimistic.rb +10 -9
  146. data/lib/active_record/locking/pessimistic.rb +10 -4
  147. data/lib/active_record/log_subscriber.rb +23 -7
  148. data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
  149. data/lib/active_record/middleware/database_selector.rb +18 -6
  150. data/lib/active_record/middleware/shard_selector.rb +60 -0
  151. data/lib/active_record/migration/command_recorder.rb +7 -7
  152. data/lib/active_record/migration/compatibility.rb +84 -2
  153. data/lib/active_record/migration/join_table.rb +1 -1
  154. data/lib/active_record/migration.rb +114 -83
  155. data/lib/active_record/model_schema.rb +58 -59
  156. data/lib/active_record/nested_attributes.rb +13 -12
  157. data/lib/active_record/no_touching.rb +3 -3
  158. data/lib/active_record/null_relation.rb +2 -6
  159. data/lib/active_record/persistence.rb +228 -60
  160. data/lib/active_record/query_cache.rb +2 -2
  161. data/lib/active_record/query_logs.rb +149 -0
  162. data/lib/active_record/querying.rb +16 -6
  163. data/lib/active_record/railtie.rb +136 -22
  164. data/lib/active_record/railties/controller_runtime.rb +1 -1
  165. data/lib/active_record/railties/databases.rake +78 -136
  166. data/lib/active_record/readonly_attributes.rb +11 -0
  167. data/lib/active_record/reflection.rb +73 -50
  168. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  169. data/lib/active_record/relation/batches.rb +6 -6
  170. data/lib/active_record/relation/calculations.rb +43 -38
  171. data/lib/active_record/relation/delegation.rb +7 -7
  172. data/lib/active_record/relation/finder_methods.rb +31 -35
  173. data/lib/active_record/relation/merger.rb +20 -13
  174. data/lib/active_record/relation/predicate_builder.rb +1 -6
  175. data/lib/active_record/relation/query_attribute.rb +5 -11
  176. data/lib/active_record/relation/query_methods.rb +276 -67
  177. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  178. data/lib/active_record/relation/spawn_methods.rb +2 -2
  179. data/lib/active_record/relation/where_clause.rb +10 -19
  180. data/lib/active_record/relation.rb +189 -88
  181. data/lib/active_record/result.rb +17 -7
  182. data/lib/active_record/runtime_registry.rb +9 -13
  183. data/lib/active_record/sanitization.rb +17 -12
  184. data/lib/active_record/schema.rb +38 -23
  185. data/lib/active_record/schema_dumper.rb +25 -19
  186. data/lib/active_record/schema_migration.rb +4 -4
  187. data/lib/active_record/scoping/default.rb +60 -13
  188. data/lib/active_record/scoping/named.rb +3 -11
  189. data/lib/active_record/scoping.rb +64 -34
  190. data/lib/active_record/serialization.rb +6 -1
  191. data/lib/active_record/signed_id.rb +3 -3
  192. data/lib/active_record/store.rb +1 -1
  193. data/lib/active_record/suppressor.rb +11 -15
  194. data/lib/active_record/tasks/database_tasks.rb +127 -60
  195. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  196. data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -13
  197. data/lib/active_record/test_databases.rb +1 -1
  198. data/lib/active_record/test_fixtures.rb +9 -6
  199. data/lib/active_record/timestamp.rb +3 -4
  200. data/lib/active_record/transactions.rb +9 -14
  201. data/lib/active_record/translation.rb +3 -3
  202. data/lib/active_record/type/adapter_specific_registry.rb +32 -7
  203. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  204. data/lib/active_record/type/internal/timezone.rb +2 -2
  205. data/lib/active_record/type/serialized.rb +1 -1
  206. data/lib/active_record/type/type_map.rb +17 -20
  207. data/lib/active_record/type.rb +1 -2
  208. data/lib/active_record/validations/associated.rb +4 -4
  209. data/lib/active_record/validations/presence.rb +2 -2
  210. data/lib/active_record/validations/uniqueness.rb +4 -4
  211. data/lib/active_record/version.rb +1 -1
  212. data/lib/active_record.rb +225 -27
  213. data/lib/arel/attributes/attribute.rb +0 -8
  214. data/lib/arel/crud.rb +28 -22
  215. data/lib/arel/delete_manager.rb +18 -4
  216. data/lib/arel/filter_predications.rb +9 -0
  217. data/lib/arel/insert_manager.rb +2 -3
  218. data/lib/arel/nodes/casted.rb +1 -1
  219. data/lib/arel/nodes/delete_statement.rb +12 -13
  220. data/lib/arel/nodes/filter.rb +10 -0
  221. data/lib/arel/nodes/function.rb +1 -0
  222. data/lib/arel/nodes/insert_statement.rb +2 -2
  223. data/lib/arel/nodes/select_core.rb +2 -2
  224. data/lib/arel/nodes/select_statement.rb +2 -2
  225. data/lib/arel/nodes/update_statement.rb +8 -3
  226. data/lib/arel/nodes.rb +1 -0
  227. data/lib/arel/predications.rb +11 -3
  228. data/lib/arel/select_manager.rb +10 -4
  229. data/lib/arel/table.rb +0 -1
  230. data/lib/arel/tree_manager.rb +0 -12
  231. data/lib/arel/update_manager.rb +18 -4
  232. data/lib/arel/visitors/dot.rb +80 -90
  233. data/lib/arel/visitors/mysql.rb +8 -2
  234. data/lib/arel/visitors/postgresql.rb +0 -10
  235. data/lib/arel/visitors/to_sql.rb +58 -2
  236. data/lib/arel.rb +2 -1
  237. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  238. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  239. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  240. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  241. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  242. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  243. metadata +53 -9
@@ -86,19 +86,30 @@ db_namespace = namespace :db do
86
86
 
87
87
  desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
88
88
  task migrate: :load_config do
89
- original_db_config = ActiveRecord::Base.connection_db_config
90
- ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
91
- ActiveRecord::Base.establish_connection(db_config)
89
+ db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
90
+
91
+ if db_configs.size == 1
92
92
  ActiveRecord::Tasks::DatabaseTasks.migrate
93
+ else
94
+ original_db_config = ActiveRecord::Base.connection_db_config
95
+ mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions(db_configs)
96
+
97
+ mapped_versions.sort.each do |version, db_configs|
98
+ db_configs.each do |db_config|
99
+ ActiveRecord::Base.establish_connection(db_config)
100
+ ActiveRecord::Tasks::DatabaseTasks.migrate(version)
101
+ end
102
+ end
93
103
  end
104
+
94
105
  db_namespace["_dump"].invoke
95
106
  ensure
96
- ActiveRecord::Base.establish_connection(original_db_config)
107
+ ActiveRecord::Base.establish_connection(original_db_config) if original_db_config
97
108
  end
98
109
 
99
- # IMPORTANT: This task won't dump the schema if ActiveRecord::Base.dump_schema_after_migration is set to false
110
+ # IMPORTANT: This task won't dump the schema if ActiveRecord.dump_schema_after_migration is set to false
100
111
  task :_dump do
101
- if ActiveRecord::Base.dump_schema_after_migration
112
+ if ActiveRecord.dump_schema_after_migration
102
113
  db_namespace["schema:dump"].invoke
103
114
  end
104
115
  # Allow this task to be called as many times as required. An example is the
@@ -108,11 +119,15 @@ db_namespace = namespace :db do
108
119
 
109
120
  namespace :_dump do
110
121
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
111
- # IMPORTANT: This task won't dump the schema if ActiveRecord::Base.dump_schema_after_migration is set to false
122
+ # IMPORTANT: This task won't dump the schema if ActiveRecord.dump_schema_after_migration is set to false
112
123
  task name do
113
- if ActiveRecord::Base.dump_schema_after_migration
124
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
125
+
126
+ if ActiveRecord.dump_schema_after_migration && db_config.schema_dump
127
+ ActiveRecord::Base.establish_connection(db_config)
114
128
  db_namespace["schema:dump:#{name}"].invoke
115
129
  end
130
+
116
131
  # Allow this task to be called as many times as required. An example is the
117
132
  # migrate:redo task, which calls other two internally that depend on this one.
118
133
  db_namespace["_dump:#{name}"].reenable
@@ -275,6 +290,7 @@ db_namespace = namespace :db do
275
290
  desc "Rolls the schema back to the previous version (specify steps w/ STEP=n)."
276
291
  task rollback: :load_config do
277
292
  ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:rollback")
293
+ raise "VERSION is not supported - To rollback a specific version, use db:migrate:down" if ENV["VERSION"]
278
294
 
279
295
  step = ENV["STEP"] ? ENV["STEP"].to_i : 1
280
296
 
@@ -290,7 +306,16 @@ db_namespace = namespace :db do
290
306
  db_namespace["_dump"].invoke
291
307
  end
292
308
 
293
- desc "Drops and recreates the database from db/schema.rb for the current environment and loads the seeds."
309
+ namespace :reset do
310
+ task all: ["db:drop", "db:setup"]
311
+
312
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
313
+ desc "Drops and recreates the #{name} database from its schema for the current environment and loads the seeds."
314
+ task name => ["db:drop:#{name}", "db:setup:#{name}"]
315
+ end
316
+ end
317
+
318
+ desc "Drops and recreates all databases from their schema for the current environment and loads the seeds."
294
319
  task reset: [ "db:drop", "db:setup" ]
295
320
 
296
321
  # desc "Retrieves the charset for the current environment's database"
@@ -307,7 +332,7 @@ db_namespace = namespace :db do
307
332
 
308
333
  desc "Retrieves the current schema version number"
309
334
  task version: :load_config do
310
- puts "Current version: #{ActiveRecord::Base.connection.migration_context.current_version}"
335
+ puts "Current version: #{ActiveRecord::Base.connection.schema_version}"
311
336
  end
312
337
 
313
338
  # desc "Raises an error if there are pending migrations"
@@ -349,41 +374,21 @@ db_namespace = namespace :db do
349
374
  end
350
375
  end
351
376
 
352
- desc "Creates the database, loads the schema, and initializes with the seed data (use db:reset to also drop the database first)"
377
+ namespace :setup do
378
+ task all: ["db:create", :environment, "db:schema:load", :seed]
379
+
380
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
381
+ desc "Creates the #{name} database, loads the schema, and initializes with the seed data (use db:reset:#{name} to also drop the database first)"
382
+ task name => ["db:create:#{name}", :environment, "db:schema:load:#{name}", "db:seed"]
383
+ end
384
+ end
385
+
386
+ desc "Creates all databases, loads all schemas, and initializes with the seed data (use db:reset to also drop all databases first)"
353
387
  task setup: ["db:create", :environment, "db:schema:load", :seed]
354
388
 
355
389
  desc "Runs setup if database does not exist, or runs migrations if it does"
356
390
  task prepare: :load_config do
357
- seed = false
358
-
359
- ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
360
- ActiveRecord::Base.establish_connection(db_config)
361
-
362
- # Skipped when no database
363
- ActiveRecord::Tasks::DatabaseTasks.migrate
364
-
365
- if ActiveRecord::Base.dump_schema_after_migration
366
- ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, ActiveRecord::Base.schema_format)
367
- end
368
- rescue ActiveRecord::NoDatabaseError
369
- config_name = db_config.name
370
- ActiveRecord::Tasks::DatabaseTasks.create_current(db_config.env_name, config_name)
371
-
372
- if File.exist?(ActiveRecord::Tasks::DatabaseTasks.dump_filename(config_name))
373
- ActiveRecord::Tasks::DatabaseTasks.load_schema(
374
- db_config,
375
- ActiveRecord::Base.schema_format,
376
- nil
377
- )
378
- else
379
- ActiveRecord::Tasks::DatabaseTasks.migrate
380
- end
381
-
382
- seed = true
383
- end
384
-
385
- ActiveRecord::Base.establish_connection
386
- ActiveRecord::Tasks::DatabaseTasks.load_seed if seed
391
+ ActiveRecord::Tasks::DatabaseTasks.prepare_all
387
392
  end
388
393
 
389
394
  desc "Loads the seed data from db/seeds.rb"
@@ -447,36 +452,32 @@ db_namespace = namespace :db do
447
452
  end
448
453
 
449
454
  namespace :schema do
450
- desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`)"
455
+ desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`)"
451
456
  task dump: :load_config do
452
457
  ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
453
- ActiveRecord::Base.establish_connection(db_config)
454
- ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config)
458
+ if db_config.schema_dump
459
+ ActiveRecord::Base.establish_connection(db_config)
460
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
461
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
462
+ end
455
463
  end
456
464
 
457
465
  db_namespace["schema:dump"].reenable
458
466
  end
459
467
 
460
- desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the database"
468
+ desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) into the database"
461
469
  task load: [:load_config, :check_protected_environments] do
462
- ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord::Base.schema_format, ENV["SCHEMA"])
463
- end
464
-
465
- task load_if_ruby: ["db:create", :environment] do
466
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
467
- Using `bin/rails db:schema:load_if_ruby` is deprecated and will be removed in Rails 7.0.
468
- Configure the format using `config.active_record.schema_format = :ruby` to use `schema.rb` and run `bin/rails db:schema:load` instead.
469
- MSG
470
- db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby
470
+ ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord.schema_format, ENV["SCHEMA"])
471
471
  end
472
472
 
473
473
  namespace :dump do
474
474
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
475
- desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) for #{name} database"
475
+ desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) for #{name} database"
476
476
  task name => :load_config do
477
477
  db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
478
478
  ActiveRecord::Base.establish_connection(db_config)
479
- ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config)
479
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
480
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
480
481
  db_namespace["schema:dump:#{name}"].reenable
481
482
  end
482
483
  end
@@ -484,10 +485,14 @@ db_namespace = namespace :db do
484
485
 
485
486
  namespace :load do
486
487
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
487
- desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the #{name} database"
488
- task name => :load_config do
488
+ desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) into the #{name} database"
489
+ task name => [:load_config, :check_protected_environments] do
490
+ original_db_config = ActiveRecord::Base.connection_db_config
489
491
  db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
490
- ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord::Base.schema_format, ENV["SCHEMA"])
492
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
493
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
494
+ ensure
495
+ ActiveRecord::Base.establish_connection(original_db_config) if original_db_config
491
496
  end
492
497
  end
493
498
  end
@@ -523,60 +528,17 @@ db_namespace = namespace :db do
523
528
  end
524
529
  end
525
530
 
526
- namespace :structure do
527
- desc "Dumps the database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
528
- task dump: :load_config do
529
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
530
- Using `bin/rails db:structure:dump` is deprecated and will be removed in Rails 7.0.
531
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:dump` instead.
532
- MSG
533
-
534
- db_namespace["schema:dump"].invoke
535
- db_namespace["structure:dump"].reenable
536
- end
531
+ namespace :encryption do
532
+ desc "Generate a set of keys for configuring Active Record encryption in a given environment"
533
+ task :init do
534
+ puts <<~MSG
535
+ Add this entry to the credentials of the target environment:#{' '}
537
536
 
538
- desc "Recreates the databases from the structure.sql file"
539
- task load: [:load_config, :check_protected_environments] do
540
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
541
- Using `bin/rails db:structure:load` is deprecated and will be removed in Rails 7.0.
542
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load` instead.
537
+ active_record_encryption:
538
+ primary_key: #{SecureRandom.alphanumeric(32)}
539
+ deterministic_key: #{SecureRandom.alphanumeric(32)}
540
+ key_derivation_salt: #{SecureRandom.alphanumeric(32)}
543
541
  MSG
544
- db_namespace["schema:load"].invoke
545
- end
546
-
547
- task load_if_sql: ["db:create", :environment] do
548
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
549
- Using `bin/rails db:structure:load_if_sql` is deprecated and will be removed in Rails 7.0.
550
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load` instead.
551
- MSG
552
- db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :sql
553
- end
554
-
555
- namespace :dump do
556
- ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
557
- desc "Dumps the #{name} database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
558
- task name => :load_config do
559
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
560
- Using `bin/rails db:structure:dump:#{name}` is deprecated and will be removed in Rails 7.0.
561
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:dump:#{name}` instead.
562
- MSG
563
- db_namespace["schema:dump:#{name}"].invoke
564
- db_namespace["structure:dump:#{name}"].reenable
565
- end
566
- end
567
- end
568
-
569
- namespace :load do
570
- ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
571
- desc "Recreates the #{name} database from the structure.sql file"
572
- task name => :load_config do
573
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
574
- Using `bin/rails db:structure:load:#{name}` is deprecated and will be removed in Rails 7.0.
575
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load:#{name}` instead.
576
- MSG
577
- db_namespace["schema:load:#{name}"].invoke
578
- end
579
- end
580
542
  end
581
543
  end
582
544
 
@@ -586,13 +548,13 @@ db_namespace = namespace :db do
586
548
  db_namespace["test:load_schema"].invoke
587
549
  end
588
550
 
589
- # desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on `config.active_record.schema_format`)"
551
+ # desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`)"
590
552
  task load_schema: %w(db:test:purge) do
591
553
  should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
592
554
  ActiveRecord::Schema.verbose = false
593
555
  ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
594
- filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.name)
595
- ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord::Base.schema_format, filename)
556
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
557
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
596
558
  end
597
559
  ensure
598
560
  if should_reconnect
@@ -600,15 +562,6 @@ db_namespace = namespace :db do
600
562
  end
601
563
  end
602
564
 
603
- # desc "Recreate the test database from an existent structure.sql file"
604
- task load_structure: %w(db:test:purge) do
605
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
606
- Using `bin/rails db:test:load_structure` is deprecated and will be removed in Rails 7.0.
607
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:test:load_schema` instead.
608
- MSG
609
- db_namespace["test:load_schema"].invoke
610
- end
611
-
612
565
  # desc "Empty the test database"
613
566
  task purge: %w(load_config check_protected_environments) do
614
567
  ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
@@ -636,9 +589,9 @@ db_namespace = namespace :db do
636
589
  task name => "db:test:purge:#{name}" do
637
590
  should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
638
591
  ActiveRecord::Schema.verbose = false
639
- filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(name)
640
592
  db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", name: name)
641
- ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord::Base.schema_format, filename)
593
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
594
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
642
595
  ensure
643
596
  if should_reconnect
644
597
  ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
@@ -646,17 +599,6 @@ db_namespace = namespace :db do
646
599
  end
647
600
  end
648
601
 
649
- # desc "Recreate the #{name} test database from an existent structure.sql file"
650
- namespace :load_structure do
651
- task name => "db:test:purge:#{name}" do
652
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
653
- Using `bin/rails db:test:load_structure:#{name}` is deprecated and will be removed in Rails 7.0.
654
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:test:load_structure:#{name}` instead.
655
- MSG
656
- db_namespace["test:load_schema:#{name}"].invoke
657
- end
658
- end
659
-
660
602
  # desc "Empty the #{name} test database"
661
603
  namespace :purge do
662
604
  task name => %w(load_config check_protected_environments) do
@@ -11,6 +11,17 @@ module ActiveRecord
11
11
  module ClassMethods
12
12
  # Attributes listed as readonly will be used to create a new record but update operations will
13
13
  # ignore these fields.
14
+ #
15
+ # You can assign a new value to a readonly attribute, but it will be ignored when the record is updated.
16
+ #
17
+ # ==== Examples
18
+ #
19
+ # class Post < ActiveRecord::Base
20
+ # attr_readonly :title
21
+ # end
22
+ #
23
+ # post = Post.create!(title: "Introducing Ruby on Rails!")
24
+ # post.update(title: "a different title") # change to title will be ignored
14
25
  def attr_readonly(*attributes)
15
26
  self._attr_readonly = Set.new(attributes.map(&:to_s)) + (_attr_readonly || [])
16
27
  end
@@ -10,6 +10,7 @@ module ActiveRecord
10
10
  included do
11
11
  class_attribute :_reflections, instance_writer: false, default: {}
12
12
  class_attribute :aggregate_reflections, instance_writer: false, default: {}
13
+ class_attribute :automatic_scope_inversing, instance_writer: false, default: false
13
14
  end
14
15
 
15
16
  class << self
@@ -115,7 +116,7 @@ module ActiveRecord
115
116
  reflections[association.to_s]
116
117
  end
117
118
 
118
- def _reflect_on_association(association) #:nodoc:
119
+ def _reflect_on_association(association) # :nodoc:
119
120
  _reflections[association.to_s]
120
121
  end
121
122
 
@@ -194,9 +195,9 @@ module ActiveRecord
194
195
  klass_scope
195
196
  end
196
197
 
197
- def join_scopes(table, predicate_builder, klass = self.klass) # :nodoc:
198
+ def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc:
198
199
  if scope
199
- [scope_for(build_scope(table, predicate_builder, klass))]
200
+ [scope_for(build_scope(table, predicate_builder, klass), record)]
200
201
  else
201
202
  []
202
203
  end
@@ -234,10 +235,13 @@ module ActiveRecord
234
235
  if has_inverse? && inverse_of.nil?
235
236
  raise InverseOfAssociationNotFoundError.new(self)
236
237
  end
238
+ if has_inverse? && inverse_of == self
239
+ raise InverseOfAssociationRecursiveError.new(self)
240
+ end
237
241
  end
238
242
  end
239
243
 
240
- # This shit is nasty. We need to avoid the following situation:
244
+ # We need to avoid the following situation:
241
245
  #
242
246
  # * An associated record is deleted via record.destroy
243
247
  # * Hence the callbacks run, and they find a belongs_to on the record with a
@@ -293,6 +297,12 @@ module ActiveRecord
293
297
  options[:strict_loading]
294
298
  end
295
299
 
300
+ def strict_loading_violation_message(owner)
301
+ message = +"`#{owner}` is marked for strict_loading."
302
+ message << " The #{polymorphic? ? "polymorphic association" : "#{klass} association"}"
303
+ message << " named `:#{name}` cannot be lazily loaded."
304
+ end
305
+
296
306
  protected
297
307
  def actual_source_reflection # FIXME: this is a horrible name
298
308
  self
@@ -306,6 +316,12 @@ module ActiveRecord
306
316
  def primary_key(klass)
307
317
  klass.primary_key || raise(UnknownPrimaryKey.new(klass))
308
318
  end
319
+
320
+ def ensure_option_not_given_as_class!(option_name)
321
+ if options[option_name] && options[option_name].class == Class
322
+ raise ArgumentError, "A class was passed to `:#{option_name}` but we are expecting a string."
323
+ end
324
+ end
309
325
  end
310
326
 
311
327
  # Base class for AggregateReflection and AssociationReflection. Objects of
@@ -392,7 +408,7 @@ module ActiveRecord
392
408
 
393
409
  # Holds all the metadata about an aggregation as it was specified in the
394
410
  # Active Record class.
395
- class AggregateReflection < MacroReflection #:nodoc:
411
+ class AggregateReflection < MacroReflection # :nodoc:
396
412
  def mapping
397
413
  mapping = options[:mapping] || [name, name]
398
414
  mapping.first.is_a?(Array) ? mapping : [mapping]
@@ -401,12 +417,29 @@ module ActiveRecord
401
417
 
402
418
  # Holds all the metadata about an association as it was specified in the
403
419
  # Active Record class.
404
- class AssociationReflection < MacroReflection #:nodoc:
420
+ class AssociationReflection < MacroReflection # :nodoc:
405
421
  def compute_class(name)
406
422
  if polymorphic?
407
423
  raise ArgumentError, "Polymorphic associations do not support computing the class."
408
424
  end
409
- active_record.send(:compute_type, name)
425
+
426
+ msg = <<-MSG.squish
427
+ Rails couldn't find a valid model for #{name} association.
428
+ Please provide the :class_name option on the association declaration.
429
+ If :class_name is already provided, make sure it's an ActiveRecord::Base subclass.
430
+ MSG
431
+
432
+ begin
433
+ klass = active_record.send(:compute_type, name)
434
+
435
+ unless klass < ActiveRecord::Base
436
+ raise ArgumentError, msg
437
+ end
438
+
439
+ klass
440
+ rescue NameError
441
+ raise NameError, msg
442
+ end
410
443
  end
411
444
 
412
445
  attr_reader :type, :foreign_type
@@ -416,11 +449,8 @@ module ActiveRecord
416
449
  super
417
450
  @type = -(options[:foreign_type]&.to_s || "#{options[:as]}_type") if options[:as]
418
451
  @foreign_type = -(options[:foreign_type]&.to_s || "#{name}_type") if options[:polymorphic]
419
- @constructable = calculate_constructable(macro, options)
420
452
 
421
- if options[:class_name] && options[:class_name].class == Class
422
- raise ArgumentError, "A class was passed to `:class_name` but we are expecting a string."
423
- end
453
+ ensure_option_not_given_as_class!(:class_name)
424
454
  end
425
455
 
426
456
  def association_scope_cache(klass, owner, &block)
@@ -431,10 +461,6 @@ module ActiveRecord
431
461
  klass.cached_find_by_statement(key, &block)
432
462
  end
433
463
 
434
- def constructable? # :nodoc:
435
- @constructable
436
- end
437
-
438
464
  def join_table
439
465
  @join_table ||= -(options[:join_table]&.to_s || derive_join_table)
440
466
  end
@@ -467,18 +493,17 @@ module ActiveRecord
467
493
  check_validity_of_inverse!
468
494
  end
469
495
 
470
- def check_preloadable!
496
+ def check_eager_loadable!
471
497
  return unless scope
472
498
 
473
499
  unless scope.arity == 0
474
500
  raise ArgumentError, <<-MSG.squish
475
501
  The association scope '#{name}' is instance dependent (the scope
476
- block takes an argument). Preloading instance dependent scopes is
477
- not supported.
502
+ block takes an argument). Eager loading instance dependent scopes
503
+ is not supported.
478
504
  MSG
479
505
  end
480
506
  end
481
- alias :check_eager_loadable! :check_preloadable!
482
507
 
483
508
  def join_id_for(owner) # :nodoc:
484
509
  owner[join_foreign_key]
@@ -563,9 +588,6 @@ module ActiveRecord
563
588
  options[:polymorphic]
564
589
  end
565
590
 
566
- VALID_AUTOMATIC_INVERSE_MACROS = [:has_many, :has_one, :belongs_to]
567
- INVALID_AUTOMATIC_INVERSE_OPTIONS = [:through, :foreign_key]
568
-
569
591
  def add_as_source(seed)
570
592
  seed
571
593
  end
@@ -583,10 +605,6 @@ module ActiveRecord
583
605
  end
584
606
 
585
607
  private
586
- def calculate_constructable(macro, options)
587
- true
588
- end
589
-
590
608
  # Attempts to find the inverse association name automatically.
591
609
  # If it cannot find a suitable inverse association name, it returns
592
610
  # +nil+.
@@ -623,9 +641,10 @@ module ActiveRecord
623
641
  # with the current reflection's klass name.
624
642
  def valid_inverse_reflection?(reflection)
625
643
  reflection &&
644
+ reflection != self &&
626
645
  foreign_key == reflection.foreign_key &&
627
646
  klass <= reflection.active_record &&
628
- can_find_inverse_of_automatically?(reflection)
647
+ can_find_inverse_of_automatically?(reflection, true)
629
648
  end
630
649
 
631
650
  # Checks to see if the reflection doesn't have any options that prevent
@@ -634,14 +653,25 @@ module ActiveRecord
634
653
  # have <tt>has_many</tt>, <tt>has_one</tt>, <tt>belongs_to</tt> associations.
635
654
  # Third, we must not have options such as <tt>:foreign_key</tt>
636
655
  # which prevent us from correctly guessing the inverse association.
637
- #
638
- # Anything with a scope can additionally ruin our attempt at finding an
639
- # inverse, so we exclude reflections with scopes.
640
- def can_find_inverse_of_automatically?(reflection)
656
+ def can_find_inverse_of_automatically?(reflection, inverse_reflection = false)
641
657
  reflection.options[:inverse_of] != false &&
642
- VALID_AUTOMATIC_INVERSE_MACROS.include?(reflection.macro) &&
643
- !INVALID_AUTOMATIC_INVERSE_OPTIONS.any? { |opt| reflection.options[opt] } &&
658
+ !reflection.options[:through] &&
659
+ !reflection.options[:foreign_key] &&
660
+ scope_allows_automatic_inverse_of?(reflection, inverse_reflection)
661
+ end
662
+
663
+ # Scopes on the potential inverse reflection prevent automatic
664
+ # <tt>inverse_of</tt>, since the scope could exclude the owner record
665
+ # we would inverse from. Scopes on the reflection itself allow for
666
+ # automatic <tt>inverse_of</tt> as long as
667
+ # <tt>config.active_record.automatic_scope_inversing<tt> is set to
668
+ # +true+ (the default for new applications).
669
+ def scope_allows_automatic_inverse_of?(reflection, inverse_reflection)
670
+ if inverse_reflection
644
671
  !reflection.scope
672
+ else
673
+ !reflection.scope || reflection.klass.automatic_scope_inversing
674
+ end
645
675
  end
646
676
 
647
677
  def derive_class_name
@@ -656,7 +686,7 @@ module ActiveRecord
656
686
  elsif options[:as]
657
687
  "#{options[:as]}_id"
658
688
  else
659
- active_record.name.foreign_key
689
+ active_record.model_name.to_s.foreign_key
660
690
  end
661
691
  end
662
692
 
@@ -691,11 +721,6 @@ module ActiveRecord
691
721
  Associations::HasOneAssociation
692
722
  end
693
723
  end
694
-
695
- private
696
- def calculate_constructable(macro, options)
697
- !options[:through]
698
- end
699
724
  end
700
725
 
701
726
  class BelongsToReflection < AssociationReflection # :nodoc:
@@ -733,13 +758,9 @@ module ActiveRecord
733
758
  end
734
759
 
735
760
  private
736
- def can_find_inverse_of_automatically?(_)
761
+ def can_find_inverse_of_automatically?(*)
737
762
  !polymorphic? && super
738
763
  end
739
-
740
- def calculate_constructable(macro, options)
741
- !polymorphic?
742
- end
743
764
  end
744
765
 
745
766
  class HasAndBelongsToManyReflection < AssociationReflection # :nodoc:
@@ -752,7 +773,7 @@ module ActiveRecord
752
773
 
753
774
  # Holds all the metadata about a :through association as it was specified
754
775
  # in the Active Record class.
755
- class ThroughReflection < AbstractReflection #:nodoc:
776
+ class ThroughReflection < AbstractReflection # :nodoc:
756
777
  delegate :foreign_key, :foreign_type, :association_foreign_key, :join_id_for, :type,
757
778
  :active_record_primary_key, :join_foreign_key, to: :source_reflection
758
779
 
@@ -760,6 +781,8 @@ module ActiveRecord
760
781
  @delegate_reflection = delegate_reflection
761
782
  @klass = delegate_reflection.options[:anonymous_class]
762
783
  @source_reflection_name = delegate_reflection.options[:source]
784
+
785
+ ensure_option_not_given_as_class!(:source_type)
763
786
  end
764
787
 
765
788
  def through_reflection?
@@ -840,8 +863,8 @@ module ActiveRecord
840
863
  source_reflection.scopes + super
841
864
  end
842
865
 
843
- def join_scopes(table, predicate_builder, klass = self.klass) # :nodoc:
844
- source_reflection.join_scopes(table, predicate_builder, klass) + super
866
+ def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc:
867
+ source_reflection.join_scopes(table, predicate_builder, klass, record) + super
845
868
  end
846
869
 
847
870
  def has_scope?
@@ -1013,9 +1036,9 @@ module ActiveRecord
1013
1036
  @previous_reflection = previous_reflection
1014
1037
  end
1015
1038
 
1016
- def join_scopes(table, predicate_builder, klass = self.klass) # :nodoc:
1017
- scopes = @previous_reflection.join_scopes(table, predicate_builder) + super
1018
- scopes << build_scope(table, predicate_builder, klass).instance_exec(nil, &source_type_scope)
1039
+ def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc:
1040
+ scopes = @previous_reflection.join_scopes(table, predicate_builder, klass, record) + super
1041
+ scopes << build_scope(table, predicate_builder, klass).instance_exec(record, &source_type_scope)
1019
1042
  end
1020
1043
 
1021
1044
  def constraints