omg-activerecord 8.0.0.alpha1

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 (412) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +355 -0
  3. data/MIT-LICENSE +22 -0
  4. data/README.rdoc +219 -0
  5. data/examples/performance.rb +185 -0
  6. data/examples/simple.rb +15 -0
  7. data/lib/active_record/aggregations.rb +287 -0
  8. data/lib/active_record/association_relation.rb +50 -0
  9. data/lib/active_record/associations/alias_tracker.rb +90 -0
  10. data/lib/active_record/associations/association.rb +417 -0
  11. data/lib/active_record/associations/association_scope.rb +175 -0
  12. data/lib/active_record/associations/belongs_to_association.rb +163 -0
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
  14. data/lib/active_record/associations/builder/association.rb +170 -0
  15. data/lib/active_record/associations/builder/belongs_to.rb +160 -0
  16. data/lib/active_record/associations/builder/collection_association.rb +80 -0
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +107 -0
  18. data/lib/active_record/associations/builder/has_many.rb +23 -0
  19. data/lib/active_record/associations/builder/has_one.rb +61 -0
  20. data/lib/active_record/associations/builder/singular_association.rb +48 -0
  21. data/lib/active_record/associations/collection_association.rb +535 -0
  22. data/lib/active_record/associations/collection_proxy.rb +1163 -0
  23. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  24. data/lib/active_record/associations/errors.rb +265 -0
  25. data/lib/active_record/associations/foreign_association.rb +40 -0
  26. data/lib/active_record/associations/has_many_association.rb +167 -0
  27. data/lib/active_record/associations/has_many_through_association.rb +232 -0
  28. data/lib/active_record/associations/has_one_association.rb +142 -0
  29. data/lib/active_record/associations/has_one_through_association.rb +45 -0
  30. data/lib/active_record/associations/join_dependency/join_association.rb +106 -0
  31. data/lib/active_record/associations/join_dependency/join_base.rb +23 -0
  32. data/lib/active_record/associations/join_dependency/join_part.rb +71 -0
  33. data/lib/active_record/associations/join_dependency.rb +301 -0
  34. data/lib/active_record/associations/nested_error.rb +47 -0
  35. data/lib/active_record/associations/preloader/association.rb +316 -0
  36. data/lib/active_record/associations/preloader/batch.rb +48 -0
  37. data/lib/active_record/associations/preloader/branch.rb +153 -0
  38. data/lib/active_record/associations/preloader/through_association.rb +150 -0
  39. data/lib/active_record/associations/preloader.rb +135 -0
  40. data/lib/active_record/associations/singular_association.rb +76 -0
  41. data/lib/active_record/associations/through_association.rb +132 -0
  42. data/lib/active_record/associations.rb +1897 -0
  43. data/lib/active_record/asynchronous_queries_tracker.rb +64 -0
  44. data/lib/active_record/attribute_assignment.rb +82 -0
  45. data/lib/active_record/attribute_methods/before_type_cast.rb +106 -0
  46. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  47. data/lib/active_record/attribute_methods/dirty.rb +262 -0
  48. data/lib/active_record/attribute_methods/primary_key.rb +158 -0
  49. data/lib/active_record/attribute_methods/query.rb +50 -0
  50. data/lib/active_record/attribute_methods/read.rb +46 -0
  51. data/lib/active_record/attribute_methods/serialization.rb +232 -0
  52. data/lib/active_record/attribute_methods/time_zone_conversion.rb +94 -0
  53. data/lib/active_record/attribute_methods/write.rb +49 -0
  54. data/lib/active_record/attribute_methods.rb +542 -0
  55. data/lib/active_record/attributes.rb +307 -0
  56. data/lib/active_record/autosave_association.rb +586 -0
  57. data/lib/active_record/base.rb +338 -0
  58. data/lib/active_record/callbacks.rb +452 -0
  59. data/lib/active_record/coders/column_serializer.rb +61 -0
  60. data/lib/active_record/coders/json.rb +15 -0
  61. data/lib/active_record/coders/yaml_column.rb +95 -0
  62. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +290 -0
  63. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +210 -0
  64. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
  65. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +923 -0
  66. data/lib/active_record/connection_adapters/abstract/database_limits.rb +31 -0
  67. data/lib/active_record/connection_adapters/abstract/database_statements.rb +747 -0
  68. data/lib/active_record/connection_adapters/abstract/query_cache.rb +319 -0
  69. data/lib/active_record/connection_adapters/abstract/quoting.rb +239 -0
  70. data/lib/active_record/connection_adapters/abstract/savepoints.rb +24 -0
  71. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +190 -0
  72. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +961 -0
  73. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +106 -0
  74. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1883 -0
  75. data/lib/active_record/connection_adapters/abstract/transaction.rb +676 -0
  76. data/lib/active_record/connection_adapters/abstract_adapter.rb +1218 -0
  77. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +1016 -0
  78. data/lib/active_record/connection_adapters/column.rb +122 -0
  79. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  80. data/lib/active_record/connection_adapters/mysql/column.rb +28 -0
  81. data/lib/active_record/connection_adapters/mysql/database_statements.rb +95 -0
  82. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  83. data/lib/active_record/connection_adapters/mysql/quoting.rb +114 -0
  84. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +106 -0
  85. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +106 -0
  86. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +97 -0
  87. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +300 -0
  88. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  89. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +96 -0
  90. data/lib/active_record/connection_adapters/mysql2_adapter.rb +196 -0
  91. data/lib/active_record/connection_adapters/pool_config.rb +83 -0
  92. data/lib/active_record/connection_adapters/pool_manager.rb +57 -0
  93. data/lib/active_record/connection_adapters/postgresql/column.rb +82 -0
  94. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +231 -0
  95. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +91 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +53 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +54 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +31 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +20 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +109 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
  109. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  110. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +42 -0
  112. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
  113. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +74 -0
  114. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +124 -0
  115. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
  116. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  117. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  118. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +125 -0
  119. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +45 -0
  120. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
  121. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
  122. data/lib/active_record/connection_adapters/postgresql/oid.rb +38 -0
  123. data/lib/active_record/connection_adapters/postgresql/quoting.rb +238 -0
  124. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +71 -0
  125. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +169 -0
  126. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +392 -0
  127. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +127 -0
  128. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +1162 -0
  129. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  130. data/lib/active_record/connection_adapters/postgresql/utils.rb +79 -0
  131. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1182 -0
  132. data/lib/active_record/connection_adapters/schema_cache.rb +478 -0
  133. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  134. data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
  135. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +145 -0
  136. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  137. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +116 -0
  138. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +37 -0
  139. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +39 -0
  140. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +47 -0
  141. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +221 -0
  142. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +843 -0
  143. data/lib/active_record/connection_adapters/statement_pool.rb +67 -0
  144. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +69 -0
  145. data/lib/active_record/connection_adapters/trilogy_adapter.rb +212 -0
  146. data/lib/active_record/connection_adapters.rb +176 -0
  147. data/lib/active_record/connection_handling.rb +413 -0
  148. data/lib/active_record/core.rb +836 -0
  149. data/lib/active_record/counter_cache.rb +230 -0
  150. data/lib/active_record/database_configurations/connection_url_resolver.rb +105 -0
  151. data/lib/active_record/database_configurations/database_config.rb +104 -0
  152. data/lib/active_record/database_configurations/hash_config.rb +172 -0
  153. data/lib/active_record/database_configurations/url_config.rb +78 -0
  154. data/lib/active_record/database_configurations.rb +309 -0
  155. data/lib/active_record/delegated_type.rb +289 -0
  156. data/lib/active_record/deprecator.rb +7 -0
  157. data/lib/active_record/destroy_association_async_job.rb +38 -0
  158. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  159. data/lib/active_record/dynamic_matchers.rb +121 -0
  160. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  161. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  162. data/lib/active_record/encryption/cipher.rb +53 -0
  163. data/lib/active_record/encryption/config.rb +70 -0
  164. data/lib/active_record/encryption/configurable.rb +60 -0
  165. data/lib/active_record/encryption/context.rb +42 -0
  166. data/lib/active_record/encryption/contexts.rb +76 -0
  167. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  168. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  169. data/lib/active_record/encryption/encryptable_record.rb +230 -0
  170. data/lib/active_record/encryption/encrypted_attribute_type.rb +184 -0
  171. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  172. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  173. data/lib/active_record/encryption/encryptor.rb +177 -0
  174. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  175. data/lib/active_record/encryption/errors.rb +15 -0
  176. data/lib/active_record/encryption/extended_deterministic_queries.rb +159 -0
  177. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  178. data/lib/active_record/encryption/key.rb +28 -0
  179. data/lib/active_record/encryption/key_generator.rb +53 -0
  180. data/lib/active_record/encryption/key_provider.rb +46 -0
  181. data/lib/active_record/encryption/message.rb +33 -0
  182. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  183. data/lib/active_record/encryption/message_serializer.rb +96 -0
  184. data/lib/active_record/encryption/null_encryptor.rb +25 -0
  185. data/lib/active_record/encryption/properties.rb +76 -0
  186. data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
  187. data/lib/active_record/encryption/scheme.rb +107 -0
  188. data/lib/active_record/encryption.rb +58 -0
  189. data/lib/active_record/enum.rb +424 -0
  190. data/lib/active_record/errors.rb +614 -0
  191. data/lib/active_record/explain.rb +63 -0
  192. data/lib/active_record/explain_registry.rb +37 -0
  193. data/lib/active_record/explain_subscriber.rb +34 -0
  194. data/lib/active_record/fixture_set/file.rb +89 -0
  195. data/lib/active_record/fixture_set/model_metadata.rb +42 -0
  196. data/lib/active_record/fixture_set/render_context.rb +19 -0
  197. data/lib/active_record/fixture_set/table_row.rb +208 -0
  198. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  199. data/lib/active_record/fixtures.rb +850 -0
  200. data/lib/active_record/future_result.rb +182 -0
  201. data/lib/active_record/gem_version.rb +17 -0
  202. data/lib/active_record/inheritance.rb +366 -0
  203. data/lib/active_record/insert_all.rb +328 -0
  204. data/lib/active_record/integration.rb +209 -0
  205. data/lib/active_record/internal_metadata.rb +164 -0
  206. data/lib/active_record/legacy_yaml_adapter.rb +15 -0
  207. data/lib/active_record/locale/en.yml +48 -0
  208. data/lib/active_record/locking/optimistic.rb +228 -0
  209. data/lib/active_record/locking/pessimistic.rb +102 -0
  210. data/lib/active_record/log_subscriber.rb +149 -0
  211. data/lib/active_record/marshalling.rb +56 -0
  212. data/lib/active_record/message_pack.rb +124 -0
  213. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  214. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  215. data/lib/active_record/middleware/database_selector.rb +87 -0
  216. data/lib/active_record/middleware/shard_selector.rb +62 -0
  217. data/lib/active_record/migration/command_recorder.rb +406 -0
  218. data/lib/active_record/migration/compatibility.rb +490 -0
  219. data/lib/active_record/migration/default_strategy.rb +22 -0
  220. data/lib/active_record/migration/execution_strategy.rb +19 -0
  221. data/lib/active_record/migration/join_table.rb +16 -0
  222. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  223. data/lib/active_record/migration.rb +1626 -0
  224. data/lib/active_record/model_schema.rb +635 -0
  225. data/lib/active_record/nested_attributes.rb +633 -0
  226. data/lib/active_record/no_touching.rb +65 -0
  227. data/lib/active_record/normalization.rb +163 -0
  228. data/lib/active_record/persistence.rb +968 -0
  229. data/lib/active_record/promise.rb +84 -0
  230. data/lib/active_record/query_cache.rb +56 -0
  231. data/lib/active_record/query_logs.rb +247 -0
  232. data/lib/active_record/query_logs_formatter.rb +30 -0
  233. data/lib/active_record/querying.rb +122 -0
  234. data/lib/active_record/railtie.rb +440 -0
  235. data/lib/active_record/railties/console_sandbox.rb +5 -0
  236. data/lib/active_record/railties/controller_runtime.rb +65 -0
  237. data/lib/active_record/railties/databases.rake +641 -0
  238. data/lib/active_record/railties/job_runtime.rb +23 -0
  239. data/lib/active_record/readonly_attributes.rb +66 -0
  240. data/lib/active_record/reflection.rb +1287 -0
  241. data/lib/active_record/relation/batches/batch_enumerator.rb +115 -0
  242. data/lib/active_record/relation/batches.rb +491 -0
  243. data/lib/active_record/relation/calculations.rb +679 -0
  244. data/lib/active_record/relation/delegation.rb +154 -0
  245. data/lib/active_record/relation/finder_methods.rb +661 -0
  246. data/lib/active_record/relation/from_clause.rb +30 -0
  247. data/lib/active_record/relation/merger.rb +192 -0
  248. data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
  249. data/lib/active_record/relation/predicate_builder/association_query_value.rb +76 -0
  250. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  251. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +60 -0
  252. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  253. data/lib/active_record/relation/predicate_builder/relation_handler.rb +24 -0
  254. data/lib/active_record/relation/predicate_builder.rb +181 -0
  255. data/lib/active_record/relation/query_attribute.rb +68 -0
  256. data/lib/active_record/relation/query_methods.rb +2235 -0
  257. data/lib/active_record/relation/record_fetch_warning.rb +52 -0
  258. data/lib/active_record/relation/spawn_methods.rb +78 -0
  259. data/lib/active_record/relation/where_clause.rb +218 -0
  260. data/lib/active_record/relation.rb +1495 -0
  261. data/lib/active_record/result.rb +249 -0
  262. data/lib/active_record/runtime_registry.rb +82 -0
  263. data/lib/active_record/sanitization.rb +254 -0
  264. data/lib/active_record/schema.rb +77 -0
  265. data/lib/active_record/schema_dumper.rb +364 -0
  266. data/lib/active_record/schema_migration.rb +106 -0
  267. data/lib/active_record/scoping/default.rb +205 -0
  268. data/lib/active_record/scoping/named.rb +202 -0
  269. data/lib/active_record/scoping.rb +136 -0
  270. data/lib/active_record/secure_password.rb +60 -0
  271. data/lib/active_record/secure_token.rb +66 -0
  272. data/lib/active_record/serialization.rb +29 -0
  273. data/lib/active_record/signed_id.rb +137 -0
  274. data/lib/active_record/statement_cache.rb +164 -0
  275. data/lib/active_record/store.rb +299 -0
  276. data/lib/active_record/suppressor.rb +59 -0
  277. data/lib/active_record/table_metadata.rb +85 -0
  278. data/lib/active_record/tasks/database_tasks.rb +681 -0
  279. data/lib/active_record/tasks/mysql_database_tasks.rb +120 -0
  280. data/lib/active_record/tasks/postgresql_database_tasks.rb +147 -0
  281. data/lib/active_record/tasks/sqlite_database_tasks.rb +89 -0
  282. data/lib/active_record/test_databases.rb +24 -0
  283. data/lib/active_record/test_fixtures.rb +321 -0
  284. data/lib/active_record/testing/query_assertions.rb +121 -0
  285. data/lib/active_record/timestamp.rb +177 -0
  286. data/lib/active_record/token_for.rb +123 -0
  287. data/lib/active_record/touch_later.rb +70 -0
  288. data/lib/active_record/transaction.rb +132 -0
  289. data/lib/active_record/transactions.rb +523 -0
  290. data/lib/active_record/translation.rb +22 -0
  291. data/lib/active_record/type/adapter_specific_registry.rb +144 -0
  292. data/lib/active_record/type/date.rb +9 -0
  293. data/lib/active_record/type/date_time.rb +9 -0
  294. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  295. data/lib/active_record/type/hash_lookup_type_map.rb +57 -0
  296. data/lib/active_record/type/internal/timezone.rb +22 -0
  297. data/lib/active_record/type/json.rb +30 -0
  298. data/lib/active_record/type/serialized.rb +76 -0
  299. data/lib/active_record/type/text.rb +11 -0
  300. data/lib/active_record/type/time.rb +35 -0
  301. data/lib/active_record/type/type_map.rb +58 -0
  302. data/lib/active_record/type/unsigned_integer.rb +16 -0
  303. data/lib/active_record/type.rb +83 -0
  304. data/lib/active_record/type_caster/connection.rb +33 -0
  305. data/lib/active_record/type_caster/map.rb +23 -0
  306. data/lib/active_record/type_caster.rb +9 -0
  307. data/lib/active_record/validations/absence.rb +25 -0
  308. data/lib/active_record/validations/associated.rb +65 -0
  309. data/lib/active_record/validations/length.rb +26 -0
  310. data/lib/active_record/validations/numericality.rb +36 -0
  311. data/lib/active_record/validations/presence.rb +45 -0
  312. data/lib/active_record/validations/uniqueness.rb +295 -0
  313. data/lib/active_record/validations.rb +101 -0
  314. data/lib/active_record/version.rb +10 -0
  315. data/lib/active_record.rb +616 -0
  316. data/lib/arel/alias_predication.rb +9 -0
  317. data/lib/arel/attributes/attribute.rb +33 -0
  318. data/lib/arel/collectors/bind.rb +31 -0
  319. data/lib/arel/collectors/composite.rb +46 -0
  320. data/lib/arel/collectors/plain_string.rb +20 -0
  321. data/lib/arel/collectors/sql_string.rb +27 -0
  322. data/lib/arel/collectors/substitute_binds.rb +35 -0
  323. data/lib/arel/crud.rb +48 -0
  324. data/lib/arel/delete_manager.rb +32 -0
  325. data/lib/arel/errors.rb +19 -0
  326. data/lib/arel/expressions.rb +29 -0
  327. data/lib/arel/factory_methods.rb +53 -0
  328. data/lib/arel/filter_predications.rb +9 -0
  329. data/lib/arel/insert_manager.rb +48 -0
  330. data/lib/arel/math.rb +45 -0
  331. data/lib/arel/nodes/ascending.rb +23 -0
  332. data/lib/arel/nodes/binary.rb +125 -0
  333. data/lib/arel/nodes/bind_param.rb +44 -0
  334. data/lib/arel/nodes/bound_sql_literal.rb +65 -0
  335. data/lib/arel/nodes/case.rb +55 -0
  336. data/lib/arel/nodes/casted.rb +62 -0
  337. data/lib/arel/nodes/comment.rb +29 -0
  338. data/lib/arel/nodes/count.rb +12 -0
  339. data/lib/arel/nodes/cte.rb +36 -0
  340. data/lib/arel/nodes/delete_statement.rb +44 -0
  341. data/lib/arel/nodes/descending.rb +23 -0
  342. data/lib/arel/nodes/equality.rb +15 -0
  343. data/lib/arel/nodes/extract.rb +24 -0
  344. data/lib/arel/nodes/false.rb +16 -0
  345. data/lib/arel/nodes/filter.rb +10 -0
  346. data/lib/arel/nodes/fragments.rb +35 -0
  347. data/lib/arel/nodes/full_outer_join.rb +8 -0
  348. data/lib/arel/nodes/function.rb +45 -0
  349. data/lib/arel/nodes/grouping.rb +11 -0
  350. data/lib/arel/nodes/homogeneous_in.rb +68 -0
  351. data/lib/arel/nodes/in.rb +15 -0
  352. data/lib/arel/nodes/infix_operation.rb +92 -0
  353. data/lib/arel/nodes/inner_join.rb +8 -0
  354. data/lib/arel/nodes/insert_statement.rb +37 -0
  355. data/lib/arel/nodes/join_source.rb +20 -0
  356. data/lib/arel/nodes/leading_join.rb +8 -0
  357. data/lib/arel/nodes/matches.rb +18 -0
  358. data/lib/arel/nodes/named_function.rb +23 -0
  359. data/lib/arel/nodes/nary.rb +39 -0
  360. data/lib/arel/nodes/node.rb +161 -0
  361. data/lib/arel/nodes/node_expression.rb +13 -0
  362. data/lib/arel/nodes/ordering.rb +27 -0
  363. data/lib/arel/nodes/outer_join.rb +8 -0
  364. data/lib/arel/nodes/over.rb +15 -0
  365. data/lib/arel/nodes/regexp.rb +16 -0
  366. data/lib/arel/nodes/right_outer_join.rb +8 -0
  367. data/lib/arel/nodes/select_core.rb +67 -0
  368. data/lib/arel/nodes/select_statement.rb +41 -0
  369. data/lib/arel/nodes/sql_literal.rb +32 -0
  370. data/lib/arel/nodes/string_join.rb +11 -0
  371. data/lib/arel/nodes/table_alias.rb +35 -0
  372. data/lib/arel/nodes/terminal.rb +16 -0
  373. data/lib/arel/nodes/true.rb +16 -0
  374. data/lib/arel/nodes/unary.rb +44 -0
  375. data/lib/arel/nodes/unary_operation.rb +20 -0
  376. data/lib/arel/nodes/unqualified_column.rb +22 -0
  377. data/lib/arel/nodes/update_statement.rb +46 -0
  378. data/lib/arel/nodes/values_list.rb +9 -0
  379. data/lib/arel/nodes/window.rb +126 -0
  380. data/lib/arel/nodes/with.rb +11 -0
  381. data/lib/arel/nodes.rb +75 -0
  382. data/lib/arel/order_predications.rb +13 -0
  383. data/lib/arel/predications.rb +260 -0
  384. data/lib/arel/select_manager.rb +276 -0
  385. data/lib/arel/table.rb +121 -0
  386. data/lib/arel/tree_manager.rb +65 -0
  387. data/lib/arel/update_manager.rb +49 -0
  388. data/lib/arel/visitors/dot.rb +299 -0
  389. data/lib/arel/visitors/mysql.rb +111 -0
  390. data/lib/arel/visitors/postgresql.rb +99 -0
  391. data/lib/arel/visitors/sqlite.rb +38 -0
  392. data/lib/arel/visitors/to_sql.rb +1033 -0
  393. data/lib/arel/visitors/visitor.rb +45 -0
  394. data/lib/arel/visitors.rb +13 -0
  395. data/lib/arel/window_predications.rb +9 -0
  396. data/lib/arel.rb +73 -0
  397. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  398. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  399. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  400. data/lib/rails/generators/active_record/migration/migration_generator.rb +76 -0
  401. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +29 -0
  402. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +48 -0
  403. data/lib/rails/generators/active_record/migration.rb +54 -0
  404. data/lib/rails/generators/active_record/model/USAGE +113 -0
  405. data/lib/rails/generators/active_record/model/model_generator.rb +94 -0
  406. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  407. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  408. data/lib/rails/generators/active_record/model/templates/module.rb.tt +7 -0
  409. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  410. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  411. data/lib/rails/generators/active_record.rb +19 -0
  412. metadata +505 -0
@@ -0,0 +1,417 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Associations
5
+ # = Active Record Associations
6
+ #
7
+ # This is the root class of all associations ('+ Foo' signifies an included module Foo):
8
+ #
9
+ # Association
10
+ # SingularAssociation
11
+ # HasOneAssociation + ForeignAssociation
12
+ # HasOneThroughAssociation + ThroughAssociation
13
+ # BelongsToAssociation
14
+ # BelongsToPolymorphicAssociation
15
+ # CollectionAssociation
16
+ # HasManyAssociation + ForeignAssociation
17
+ # HasManyThroughAssociation + ThroughAssociation
18
+ #
19
+ # Associations in Active Record are middlemen between the object that
20
+ # holds the association, known as the <tt>owner</tt>, and the associated
21
+ # result set, known as the <tt>target</tt>. Association metadata is available in
22
+ # <tt>reflection</tt>, which is an instance of +ActiveRecord::Reflection::AssociationReflection+.
23
+ #
24
+ # For example, given
25
+ #
26
+ # class Blog < ActiveRecord::Base
27
+ # has_many :posts
28
+ # end
29
+ #
30
+ # blog = Blog.first
31
+ #
32
+ # The association of <tt>blog.posts</tt> has the object +blog+ as its
33
+ # <tt>owner</tt>, the collection of its posts as <tt>target</tt>, and
34
+ # the <tt>reflection</tt> object represents a <tt>:has_many</tt> macro.
35
+ class Association # :nodoc:
36
+ attr_accessor :owner
37
+ attr_reader :reflection, :disable_joins
38
+
39
+ delegate :options, to: :reflection
40
+
41
+ def initialize(owner, reflection)
42
+ reflection.check_validity!
43
+
44
+ @owner, @reflection = owner, reflection
45
+ @disable_joins = @reflection.options[:disable_joins] || false
46
+
47
+ reset
48
+ reset_scope
49
+
50
+ @skip_strict_loading = nil
51
+ end
52
+
53
+ def target
54
+ if @target.is_a?(Promise)
55
+ @target = @target.value
56
+ end
57
+ @target
58
+ end
59
+
60
+ # Resets the \loaded flag to +false+ and sets the \target to +nil+.
61
+ def reset
62
+ @loaded = false
63
+ @stale_state = nil
64
+ end
65
+
66
+ def reset_negative_cache # :nodoc:
67
+ reset if loaded? && target.nil?
68
+ end
69
+
70
+ # Reloads the \target and returns +self+ on success.
71
+ # The QueryCache is cleared if +force+ is true.
72
+ def reload(force = false)
73
+ klass.connection_pool.clear_query_cache if force && klass
74
+ reset
75
+ reset_scope
76
+ load_target
77
+ self unless target.nil?
78
+ end
79
+
80
+ # Has the \target been already \loaded?
81
+ def loaded?
82
+ @loaded
83
+ end
84
+
85
+ # Asserts the \target has been loaded setting the \loaded flag to +true+.
86
+ def loaded!
87
+ @loaded = true
88
+ @stale_state = stale_state
89
+ end
90
+
91
+ # The target is stale if the target no longer points to the record(s) that the
92
+ # relevant foreign_key(s) refers to. If stale, the association accessor method
93
+ # on the owner will reload the target. It's up to subclasses to implement the
94
+ # stale_state method if relevant.
95
+ #
96
+ # Note that if the target has not been loaded, it is not considered stale.
97
+ def stale_target?
98
+ loaded? && @stale_state != stale_state
99
+ end
100
+
101
+ # Sets the target of this association to <tt>\target</tt>, and the \loaded flag to +true+.
102
+ def target=(target)
103
+ @target = target
104
+ loaded!
105
+ end
106
+
107
+ def scope
108
+ if disable_joins
109
+ DisableJoinsAssociationScope.create.scope(self)
110
+ elsif (scope = klass.current_scope) && scope.try(:proxy_association) == self
111
+ scope.spawn
112
+ elsif scope = klass.global_current_scope
113
+ target_scope.merge!(association_scope).merge!(scope)
114
+ else
115
+ target_scope.merge!(association_scope)
116
+ end
117
+ end
118
+
119
+ def reset_scope
120
+ @association_scope = nil
121
+ end
122
+
123
+ # Set the inverse association, if possible
124
+ def set_inverse_instance(record)
125
+ if inverse = inverse_association_for(record)
126
+ inverse.inversed_from(owner)
127
+ end
128
+ record
129
+ end
130
+
131
+ def set_inverse_instance_from_queries(record)
132
+ if inverse = inverse_association_for(record)
133
+ inverse.inversed_from_queries(owner)
134
+ end
135
+ record
136
+ end
137
+
138
+ # Remove the inverse association, if possible
139
+ def remove_inverse_instance(record)
140
+ if inverse = inverse_association_for(record)
141
+ inverse.inversed_from(nil)
142
+ end
143
+ end
144
+
145
+ def inversed_from(record)
146
+ self.target = record
147
+ end
148
+
149
+ def inversed_from_queries(record)
150
+ if inversable?(record)
151
+ self.target = record
152
+ end
153
+ end
154
+
155
+ # Returns the class of the target. belongs_to polymorphic overrides this to look at the
156
+ # polymorphic_type field on the owner.
157
+ def klass
158
+ reflection.klass
159
+ end
160
+
161
+ def extensions
162
+ extensions = klass.default_extensions | reflection.extensions
163
+
164
+ if reflection.scope
165
+ extensions |= reflection.scope_for(klass.unscoped, owner).extensions
166
+ end
167
+
168
+ extensions
169
+ end
170
+
171
+ # Loads the \target if needed and returns it.
172
+ #
173
+ # This method is abstract in the sense that it relies on +find_target+,
174
+ # which is expected to be provided by descendants.
175
+ #
176
+ # If the \target is already \loaded it is just returned. Thus, you can call
177
+ # +load_target+ unconditionally to get the \target.
178
+ #
179
+ # ActiveRecord::RecordNotFound is rescued within the method, and it is
180
+ # not reraised. The proxy is \reset and +nil+ is the return value.
181
+ def load_target
182
+ @target = find_target(async: false) if (@stale_state && stale_target?) || find_target?
183
+
184
+ loaded! unless loaded?
185
+ target
186
+ rescue ActiveRecord::RecordNotFound
187
+ reset
188
+ end
189
+
190
+ def async_load_target # :nodoc:
191
+ @target = find_target(async: true) if (@stale_state && stale_target?) || find_target?
192
+
193
+ loaded! unless loaded?
194
+ nil
195
+ end
196
+
197
+ # We can't dump @reflection and @through_reflection since it contains the scope proc
198
+ def marshal_dump
199
+ ivars = (instance_variables - [:@reflection, :@through_reflection]).map { |name| [name, instance_variable_get(name)] }
200
+ [@reflection.name, ivars]
201
+ end
202
+
203
+ def marshal_load(data)
204
+ reflection_name, ivars = data
205
+ ivars.each { |name, val| instance_variable_set(name, val) }
206
+ @reflection = @owner.class._reflect_on_association(reflection_name)
207
+ end
208
+
209
+ def initialize_attributes(record, except_from_scope_attributes = nil) # :nodoc:
210
+ except_from_scope_attributes ||= {}
211
+ skip_assign = [reflection.foreign_key, reflection.type].compact
212
+ assigned_keys = record.changed_attribute_names_to_save
213
+ assigned_keys += except_from_scope_attributes.keys.map(&:to_s)
214
+ attributes = scope_for_create.except!(*(assigned_keys - skip_assign))
215
+ record.send(:_assign_attributes, attributes) if attributes.any?
216
+ set_inverse_instance(record)
217
+ end
218
+
219
+ def create(attributes = nil, &block)
220
+ _create_record(attributes, &block)
221
+ end
222
+
223
+ def create!(attributes = nil, &block)
224
+ _create_record(attributes, true, &block)
225
+ end
226
+
227
+ # Whether the association represent a single record
228
+ # or a collection of records.
229
+ def collection?
230
+ false
231
+ end
232
+
233
+ private
234
+ # Reader and writer methods call this so that consistent errors are presented
235
+ # when the association target class does not exist.
236
+ def ensure_klass_exists!
237
+ klass
238
+ end
239
+
240
+ def find_target(async: false)
241
+ if violates_strict_loading?
242
+ Base.strict_loading_violation!(owner: owner.class, reflection: reflection)
243
+ end
244
+
245
+ scope = self.scope
246
+ if skip_statement_cache?(scope)
247
+ if async
248
+ return scope.load_async.then(&:to_a)
249
+ else
250
+ return scope.to_a
251
+ end
252
+ end
253
+
254
+ sc = reflection.association_scope_cache(klass, owner) do |params|
255
+ as = AssociationScope.create { params.bind }
256
+ target_scope.merge!(as.scope(self))
257
+ end
258
+
259
+ binds = AssociationScope.get_bind_values(owner, reflection.chain)
260
+ klass.with_connection do |c|
261
+ sc.execute(binds, c, async: async) do |record|
262
+ set_inverse_instance(record)
263
+ if owner.strict_loading_n_plus_one_only? && reflection.macro == :has_many
264
+ record.strict_loading!
265
+ else
266
+ record.strict_loading!(false, mode: owner.strict_loading_mode)
267
+ end
268
+ end
269
+ end
270
+ end
271
+
272
+ def skip_strict_loading(&block)
273
+ skip_strict_loading_was = @skip_strict_loading
274
+ @skip_strict_loading = true
275
+ yield
276
+ ensure
277
+ @skip_strict_loading = skip_strict_loading_was
278
+ end
279
+
280
+ def violates_strict_loading?
281
+ return if @skip_strict_loading
282
+
283
+ return unless owner.validation_context.nil?
284
+
285
+ return reflection.strict_loading? if reflection.options.key?(:strict_loading)
286
+
287
+ owner.strict_loading? && !owner.strict_loading_n_plus_one_only?
288
+ end
289
+
290
+ # The scope for this association.
291
+ #
292
+ # Note that the association_scope is merged into the target_scope only when the
293
+ # scope method is called. This is because at that point the call may be surrounded
294
+ # by scope.scoping { ... } or unscoped { ... } etc, which affects the scope which
295
+ # actually gets built.
296
+ def association_scope
297
+ if klass
298
+ @association_scope ||= if disable_joins
299
+ DisableJoinsAssociationScope.scope(self)
300
+ else
301
+ AssociationScope.scope(self)
302
+ end
303
+ end
304
+ end
305
+
306
+ # Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
307
+ # through association's scope)
308
+ def target_scope
309
+ AssociationRelation.create(klass, self).merge!(klass.scope_for_association)
310
+ end
311
+
312
+ def scope_for_create
313
+ scope.scope_for_create
314
+ end
315
+
316
+ def find_target?
317
+ !loaded? && (!owner.new_record? || foreign_key_present?) && klass
318
+ end
319
+
320
+ # Returns true if there is a foreign key present on the owner which
321
+ # references the target. This is used to determine whether we can load
322
+ # the target if the owner is currently a new record (and therefore
323
+ # without a key). If the owner is a new record then foreign_key must
324
+ # be present in order to load target.
325
+ #
326
+ # Currently implemented by belongs_to (vanilla and polymorphic) and
327
+ # has_one/has_many :through associations which go through a belongs_to.
328
+ def foreign_key_present?
329
+ false
330
+ end
331
+
332
+ # Raises ActiveRecord::AssociationTypeMismatch unless +record+ is of
333
+ # the kind of the class of the associated objects. Meant to be used as
334
+ # a safety check when you are about to assign an associated record.
335
+ def raise_on_type_mismatch!(record)
336
+ unless record.is_a?(reflection.klass)
337
+ fresh_class = reflection.class_name.safe_constantize
338
+ unless fresh_class && record.is_a?(fresh_class)
339
+ message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, "\
340
+ "got #{record.inspect} which is an instance of #{record.class}(##{record.class.object_id})"
341
+ raise ActiveRecord::AssociationTypeMismatch, message
342
+ end
343
+ end
344
+ end
345
+
346
+ def inverse_association_for(record)
347
+ if invertible_for?(record)
348
+ record.association(inverse_reflection_for(record).name)
349
+ end
350
+ end
351
+
352
+ # Can be redefined by subclasses, notably polymorphic belongs_to
353
+ # The record parameter is necessary to support polymorphic inverses as we must check for
354
+ # the association in the specific class of the record.
355
+ def inverse_reflection_for(record)
356
+ reflection.inverse_of
357
+ end
358
+
359
+ # Returns true if inverse association on the given record needs to be set.
360
+ # This method is redefined by subclasses.
361
+ def invertible_for?(record)
362
+ foreign_key_for?(record) && inverse_reflection_for(record)
363
+ end
364
+
365
+ # Returns true if record contains the foreign_key
366
+ def foreign_key_for?(record)
367
+ foreign_key = Array(reflection.foreign_key)
368
+ foreign_key.all? { |key| record._has_attribute?(key) }
369
+ end
370
+
371
+ # This should be implemented to return the values of the relevant key(s) on the owner,
372
+ # so that when stale_state is different from the value stored on the last find_target,
373
+ # the target is stale.
374
+ #
375
+ # This is only relevant to certain associations, which is why it returns +nil+ by default.
376
+ def stale_state
377
+ end
378
+
379
+ def build_record(attributes)
380
+ reflection.build_association(attributes) do |record|
381
+ initialize_attributes(record, attributes)
382
+ yield(record) if block_given?
383
+ end
384
+ end
385
+
386
+ # Returns true if statement cache should be skipped on the association reader.
387
+ def skip_statement_cache?(scope)
388
+ reflection.has_scope? ||
389
+ scope.eager_loading? ||
390
+ klass.scope_attributes? ||
391
+ reflection.source_reflection.active_record.default_scopes.any?
392
+ end
393
+
394
+ def enqueue_destroy_association(options)
395
+ job_class = owner.class.destroy_association_async_job
396
+
397
+ if job_class
398
+ owner._after_commit_jobs.push([job_class, options])
399
+ end
400
+ end
401
+
402
+ def inversable?(record)
403
+ record &&
404
+ ((!record.persisted? || !owner.persisted?) || matches_foreign_key?(record))
405
+ end
406
+
407
+ def matches_foreign_key?(record)
408
+ if foreign_key_for?(record)
409
+ record.read_attribute(reflection.foreign_key) == owner.id ||
410
+ (foreign_key_for?(owner) && owner.read_attribute(reflection.foreign_key) == record.id)
411
+ else
412
+ owner.read_attribute(reflection.foreign_key) == record.id
413
+ end
414
+ end
415
+ end
416
+ end
417
+ end
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Associations
5
+ class AssociationScope # :nodoc:
6
+ def self.scope(association)
7
+ INSTANCE.scope(association)
8
+ end
9
+
10
+ def self.create(&block)
11
+ block ||= lambda { |val| val }
12
+ new(block)
13
+ end
14
+
15
+ def initialize(value_transformation)
16
+ @value_transformation = value_transformation
17
+ end
18
+
19
+ INSTANCE = create
20
+
21
+ def scope(association)
22
+ klass = association.klass
23
+ reflection = association.reflection
24
+ scope = klass.unscoped
25
+ owner = association.owner
26
+ chain = get_chain(reflection, association, scope.alias_tracker)
27
+
28
+ scope.extending! reflection.extensions
29
+ scope = add_constraints(scope, owner, chain)
30
+ scope.limit!(1) unless reflection.collection?
31
+ scope
32
+ end
33
+
34
+ def self.get_bind_values(owner, chain)
35
+ binds = []
36
+ last_reflection = chain.last
37
+
38
+ binds.push(*last_reflection.join_id_for(owner))
39
+ if last_reflection.type
40
+ binds << owner.class.polymorphic_name
41
+ end
42
+
43
+ chain.each_cons(2).each do |reflection, next_reflection|
44
+ if reflection.type
45
+ binds << next_reflection.klass.polymorphic_name
46
+ end
47
+ end
48
+ binds
49
+ end
50
+
51
+ private
52
+ attr_reader :value_transformation
53
+
54
+ def join(table, constraint)
55
+ Arel::Nodes::LeadingJoin.new(table, Arel::Nodes::On.new(constraint))
56
+ end
57
+
58
+ def last_chain_scope(scope, reflection, owner)
59
+ primary_key = Array(reflection.join_primary_key)
60
+ foreign_key = Array(reflection.join_foreign_key)
61
+
62
+ table = reflection.aliased_table
63
+ primary_key_foreign_key_pairs = primary_key.zip(foreign_key)
64
+ primary_key_foreign_key_pairs.each do |join_key, foreign_key|
65
+ value = transform_value(owner._read_attribute(foreign_key))
66
+ scope = apply_scope(scope, table, join_key, value)
67
+ end
68
+
69
+ if reflection.type
70
+ polymorphic_type = transform_value(owner.class.polymorphic_name)
71
+ scope = apply_scope(scope, table, reflection.type, polymorphic_type)
72
+ end
73
+
74
+ scope
75
+ end
76
+
77
+ def transform_value(value)
78
+ value_transformation.call(value)
79
+ end
80
+
81
+ def next_chain_scope(scope, reflection, next_reflection)
82
+ primary_key = Array(reflection.join_primary_key)
83
+ foreign_key = Array(reflection.join_foreign_key)
84
+
85
+ table = reflection.aliased_table
86
+ foreign_table = next_reflection.aliased_table
87
+
88
+ primary_key_foreign_key_pairs = primary_key.zip(foreign_key)
89
+ constraints = primary_key_foreign_key_pairs.map do |join_primary_key, foreign_key|
90
+ table[join_primary_key].eq(foreign_table[foreign_key])
91
+ end.inject(&:and)
92
+
93
+ if reflection.type
94
+ value = transform_value(next_reflection.klass.polymorphic_name)
95
+ scope = apply_scope(scope, table, reflection.type, value)
96
+ end
97
+
98
+ scope.joins!(join(foreign_table, constraints))
99
+ end
100
+
101
+ class ReflectionProxy < SimpleDelegator # :nodoc:
102
+ attr_reader :aliased_table
103
+
104
+ def initialize(reflection, aliased_table)
105
+ super(reflection)
106
+ @aliased_table = aliased_table
107
+ end
108
+
109
+ def all_includes; nil; end
110
+ end
111
+
112
+ def get_chain(reflection, association, tracker)
113
+ name = reflection.name
114
+ chain = [Reflection::RuntimeReflection.new(reflection, association)]
115
+ reflection.chain.drop(1).each do |refl|
116
+ aliased_table = tracker.aliased_table_for(refl.klass.arel_table) do
117
+ refl.alias_candidate(name)
118
+ end
119
+ chain << ReflectionProxy.new(refl, aliased_table)
120
+ end
121
+ chain
122
+ end
123
+
124
+ def add_constraints(scope, owner, chain)
125
+ scope = last_chain_scope(scope, chain.last, owner)
126
+
127
+ chain.each_cons(2) do |reflection, next_reflection|
128
+ scope = next_chain_scope(scope, reflection, next_reflection)
129
+ end
130
+
131
+ chain_head = chain.first
132
+ chain.reverse_each do |reflection|
133
+ reflection.constraints.each do |scope_chain_item|
134
+ item = eval_scope(reflection, scope_chain_item, owner)
135
+
136
+ if scope_chain_item == chain_head.scope
137
+ scope.merge! item.except(:where, :includes, :unscope, :order)
138
+ elsif !item.references_values.empty?
139
+ scope.merge! item.only(:joins, :left_outer_joins)
140
+
141
+ associations = item.eager_load_values | item.includes_values
142
+
143
+ unless associations.empty?
144
+ scope.joins! item.construct_join_dependency(associations, Arel::Nodes::OuterJoin)
145
+ end
146
+ end
147
+
148
+ reflection.all_includes do
149
+ scope.includes_values |= item.includes_values
150
+ end
151
+
152
+ scope.unscope!(*item.unscope_values)
153
+ scope.where_clause += item.where_clause
154
+ scope.order_values = item.order_values | scope.order_values
155
+ end
156
+ end
157
+
158
+ scope
159
+ end
160
+
161
+ def apply_scope(scope, table, key, value)
162
+ if scope.table == table
163
+ scope.where!(key => value)
164
+ else
165
+ scope.where!(table.name => { key => value })
166
+ end
167
+ end
168
+
169
+ def eval_scope(reflection, scope, owner)
170
+ relation = reflection.build_scope(reflection.aliased_table)
171
+ relation.instance_exec(owner, &scope) || relation
172
+ end
173
+ end
174
+ end
175
+ end