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,1163 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Associations
5
+ # = Active Record Collection Proxy
6
+ #
7
+ # Collection proxies in Active Record are middlemen between an
8
+ # <tt>association</tt>, and its <tt>target</tt> result set.
9
+ #
10
+ # For example, given
11
+ #
12
+ # class Blog < ActiveRecord::Base
13
+ # has_many :posts
14
+ # end
15
+ #
16
+ # blog = Blog.first
17
+ #
18
+ # The collection proxy returned by <tt>blog.posts</tt> is built from a
19
+ # <tt>:has_many</tt> <tt>association</tt>, and delegates to a collection
20
+ # of posts as the <tt>target</tt>.
21
+ #
22
+ # This class delegates unknown methods to the <tt>association</tt>'s
23
+ # relation class via a delegate cache.
24
+ #
25
+ # The <tt>target</tt> result set is not loaded until needed. For example,
26
+ #
27
+ # blog.posts.count
28
+ #
29
+ # is computed directly through SQL and does not trigger by itself the
30
+ # instantiation of the actual post records.
31
+ class CollectionProxy < Relation
32
+ def initialize(klass, association, **) # :nodoc:
33
+ @association = association
34
+ super klass
35
+
36
+ extensions = association.extensions
37
+ extend(*extensions) if extensions.any?
38
+ end
39
+
40
+ def target
41
+ @association.target
42
+ end
43
+
44
+ def load_target
45
+ @association.load_target
46
+ end
47
+
48
+ # Returns +true+ if the association has been loaded, otherwise +false+.
49
+ #
50
+ # person.pets.loaded? # => false
51
+ # person.pets.records
52
+ # person.pets.loaded? # => true
53
+ def loaded?
54
+ @association.loaded?
55
+ end
56
+ alias :loaded :loaded?
57
+
58
+ ##
59
+ # :method: select
60
+ #
61
+ # :call-seq:
62
+ # select(*fields, &block)
63
+ #
64
+ # Works in two ways.
65
+ #
66
+ # *First:* Specify a subset of fields to be selected from the result set.
67
+ #
68
+ # class Person < ActiveRecord::Base
69
+ # has_many :pets
70
+ # end
71
+ #
72
+ # person.pets
73
+ # # => [
74
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
75
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
76
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
77
+ # # ]
78
+ #
79
+ # person.pets.select(:name)
80
+ # # => [
81
+ # # #<Pet id: nil, name: "Fancy-Fancy">,
82
+ # # #<Pet id: nil, name: "Spook">,
83
+ # # #<Pet id: nil, name: "Choo-Choo">
84
+ # # ]
85
+ #
86
+ # person.pets.select(:id, :name)
87
+ # # => [
88
+ # # #<Pet id: 1, name: "Fancy-Fancy">,
89
+ # # #<Pet id: 2, name: "Spook">,
90
+ # # #<Pet id: 3, name: "Choo-Choo">
91
+ # # ]
92
+ #
93
+ # Be careful because this also means you're initializing a model
94
+ # object with only the fields that you've selected. If you attempt
95
+ # to access a field except +id+ that is not in the initialized record you'll
96
+ # receive:
97
+ #
98
+ # person.pets.select(:name).first.person_id
99
+ # # => ActiveModel::MissingAttributeError: missing attribute 'person_id' for Pet
100
+ #
101
+ # *Second:* You can pass a block so it can be used just like <tt>Array#select</tt>.
102
+ # This builds an array of objects from the database for the scope,
103
+ # converting them into an array and iterating through them using
104
+ # <tt>Array#select</tt>.
105
+ #
106
+ # person.pets.select { |pet| /oo/.match?(pet.name) }
107
+ # # => [
108
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
109
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
110
+ # # ]
111
+
112
+ # Finds an object in the collection responding to the +id+. Uses the same
113
+ # rules as ActiveRecord::FinderMethods.find. Returns ActiveRecord::RecordNotFound
114
+ # error if the object cannot be found.
115
+ #
116
+ # class Person < ActiveRecord::Base
117
+ # has_many :pets
118
+ # end
119
+ #
120
+ # person.pets
121
+ # # => [
122
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
123
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
124
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
125
+ # # ]
126
+ #
127
+ # person.pets.find(1) # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
128
+ # person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=4
129
+ #
130
+ # person.pets.find(2) { |pet| pet.name.downcase! }
131
+ # # => #<Pet id: 2, name: "fancy-fancy", person_id: 1>
132
+ #
133
+ # person.pets.find(2, 3)
134
+ # # => [
135
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
136
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
137
+ # # ]
138
+ def find(*args)
139
+ return super if block_given?
140
+ @association.find(*args)
141
+ end
142
+
143
+ ##
144
+ # :method: first
145
+ #
146
+ # :call-seq:
147
+ # first(limit = nil)
148
+ #
149
+ # Returns the first record, or the first +n+ records, from the collection.
150
+ # If the collection is empty, the first form returns +nil+, and the second
151
+ # form returns an empty array.
152
+ #
153
+ # class Person < ActiveRecord::Base
154
+ # has_many :pets
155
+ # end
156
+ #
157
+ # person.pets
158
+ # # => [
159
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
160
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
161
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
162
+ # # ]
163
+ #
164
+ # person.pets.first # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
165
+ #
166
+ # person.pets.first(2)
167
+ # # => [
168
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
169
+ # # #<Pet id: 2, name: "Spook", person_id: 1>
170
+ # # ]
171
+ #
172
+ # another_person_without.pets # => []
173
+ # another_person_without.pets.first # => nil
174
+ # another_person_without.pets.first(3) # => []
175
+
176
+ ##
177
+ # :method: second
178
+ #
179
+ # :call-seq:
180
+ # second()
181
+ #
182
+ # Same as #first except returns only the second record.
183
+
184
+ ##
185
+ # :method: third
186
+ #
187
+ # :call-seq:
188
+ # third()
189
+ #
190
+ # Same as #first except returns only the third record.
191
+
192
+ ##
193
+ # :method: fourth
194
+ #
195
+ # :call-seq:
196
+ # fourth()
197
+ #
198
+ # Same as #first except returns only the fourth record.
199
+
200
+ ##
201
+ # :method: fifth
202
+ #
203
+ # :call-seq:
204
+ # fifth()
205
+ #
206
+ # Same as #first except returns only the fifth record.
207
+
208
+ ##
209
+ # :method: forty_two
210
+ #
211
+ # :call-seq:
212
+ # forty_two()
213
+ #
214
+ # Same as #first except returns only the forty second record.
215
+ # Also known as accessing "the reddit".
216
+
217
+ ##
218
+ # :method: third_to_last
219
+ #
220
+ # :call-seq:
221
+ # third_to_last()
222
+ #
223
+ # Same as #last except returns only the third-to-last record.
224
+
225
+ ##
226
+ # :method: second_to_last
227
+ #
228
+ # :call-seq:
229
+ # second_to_last()
230
+ #
231
+ # Same as #last except returns only the second-to-last record.
232
+
233
+ # Returns the last record, or the last +n+ records, from the collection.
234
+ # If the collection is empty, the first form returns +nil+, and the second
235
+ # form returns an empty array.
236
+ #
237
+ # class Person < ActiveRecord::Base
238
+ # has_many :pets
239
+ # end
240
+ #
241
+ # person.pets
242
+ # # => [
243
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
244
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
245
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
246
+ # # ]
247
+ #
248
+ # person.pets.last # => #<Pet id: 3, name: "Choo-Choo", person_id: 1>
249
+ #
250
+ # person.pets.last(2)
251
+ # # => [
252
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
253
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
254
+ # # ]
255
+ #
256
+ # another_person_without.pets # => []
257
+ # another_person_without.pets.last # => nil
258
+ # another_person_without.pets.last(3) # => []
259
+ def last(limit = nil)
260
+ load_target if find_from_target?
261
+ super
262
+ end
263
+
264
+ # Gives a record (or N records if a parameter is supplied) from the collection
265
+ # using the same rules as ActiveRecord::FinderMethods.take.
266
+ #
267
+ # class Person < ActiveRecord::Base
268
+ # has_many :pets
269
+ # end
270
+ #
271
+ # person.pets
272
+ # # => [
273
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
274
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
275
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
276
+ # # ]
277
+ #
278
+ # person.pets.take # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
279
+ #
280
+ # person.pets.take(2)
281
+ # # => [
282
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
283
+ # # #<Pet id: 2, name: "Spook", person_id: 1>
284
+ # # ]
285
+ #
286
+ # another_person_without.pets # => []
287
+ # another_person_without.pets.take # => nil
288
+ # another_person_without.pets.take(2) # => []
289
+ def take(limit = nil)
290
+ load_target if find_from_target?
291
+ super
292
+ end
293
+
294
+ # Returns a new object of the collection type that has been instantiated
295
+ # with +attributes+ and linked to this object, but have not yet been saved.
296
+ # You can pass an array of attributes hashes, this will return an array
297
+ # with the new objects.
298
+ #
299
+ # class Person
300
+ # has_many :pets
301
+ # end
302
+ #
303
+ # person.pets.build
304
+ # # => #<Pet id: nil, name: nil, person_id: 1>
305
+ #
306
+ # person.pets.build(name: 'Fancy-Fancy')
307
+ # # => #<Pet id: nil, name: "Fancy-Fancy", person_id: 1>
308
+ #
309
+ # person.pets.build([{name: 'Spook'}, {name: 'Choo-Choo'}, {name: 'Brain'}])
310
+ # # => [
311
+ # # #<Pet id: nil, name: "Spook", person_id: 1>,
312
+ # # #<Pet id: nil, name: "Choo-Choo", person_id: 1>,
313
+ # # #<Pet id: nil, name: "Brain", person_id: 1>
314
+ # # ]
315
+ #
316
+ # person.pets.size # => 5 # size of the collection
317
+ # person.pets.count # => 0 # count from database
318
+ def build(attributes = {}, &block)
319
+ @association.build(attributes, &block)
320
+ end
321
+ alias_method :new, :build
322
+
323
+ # Returns a new object of the collection type that has been instantiated with
324
+ # attributes, linked to this object and that has already been saved (if it
325
+ # passes the validations).
326
+ #
327
+ # class Person
328
+ # has_many :pets
329
+ # end
330
+ #
331
+ # person.pets.create(name: 'Fancy-Fancy')
332
+ # # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
333
+ #
334
+ # person.pets.create([{name: 'Spook'}, {name: 'Choo-Choo'}])
335
+ # # => [
336
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
337
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
338
+ # # ]
339
+ #
340
+ # person.pets.size # => 3
341
+ # person.pets.count # => 3
342
+ #
343
+ # person.pets.find(1, 2, 3)
344
+ # # => [
345
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
346
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
347
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
348
+ # # ]
349
+ def create(attributes = {}, &block)
350
+ @association.create(attributes, &block)
351
+ end
352
+
353
+ # Like #create, except that if the record is invalid, raises an exception.
354
+ #
355
+ # class Person
356
+ # has_many :pets
357
+ # end
358
+ #
359
+ # class Pet
360
+ # validates :name, presence: true
361
+ # end
362
+ #
363
+ # person.pets.create!(name: nil)
364
+ # # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
365
+ def create!(attributes = {}, &block)
366
+ @association.create!(attributes, &block)
367
+ end
368
+
369
+ # Replaces this collection with +other_array+. This will perform a diff
370
+ # and delete/add only records that have changed.
371
+ #
372
+ # class Person < ActiveRecord::Base
373
+ # has_many :pets
374
+ # end
375
+ #
376
+ # person.pets
377
+ # # => [#<Pet id: 1, name: "Gorby", group: "cats", person_id: 1>]
378
+ #
379
+ # other_pets = [Pet.new(name: 'Puff', group: 'celebrities')]
380
+ #
381
+ # person.pets.replace(other_pets)
382
+ #
383
+ # person.pets
384
+ # # => [#<Pet id: 2, name: "Puff", group: "celebrities", person_id: 1>]
385
+ #
386
+ # If the supplied array has an incorrect association type, it raises
387
+ # an ActiveRecord::AssociationTypeMismatch error:
388
+ #
389
+ # person.pets.replace(["doo", "ggie", "gaga"])
390
+ # # => ActiveRecord::AssociationTypeMismatch: Pet expected, got String
391
+ def replace(other_array)
392
+ @association.replace(other_array)
393
+ end
394
+
395
+ # Deletes all the records from the collection according to the strategy
396
+ # specified by the +:dependent+ option. If no +:dependent+ option is given,
397
+ # then it will follow the default strategy.
398
+ #
399
+ # For <tt>has_many :through</tt> associations, the default deletion strategy is
400
+ # +:delete_all+.
401
+ #
402
+ # For +has_many+ associations, the default deletion strategy is +:nullify+.
403
+ # This sets the foreign keys to +NULL+.
404
+ #
405
+ # class Person < ActiveRecord::Base
406
+ # has_many :pets # dependent: :nullify option by default
407
+ # end
408
+ #
409
+ # person.pets.size # => 3
410
+ # person.pets
411
+ # # => [
412
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
413
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
414
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
415
+ # # ]
416
+ #
417
+ # person.pets.delete_all
418
+ # # => [
419
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
420
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
421
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
422
+ # # ]
423
+ #
424
+ # person.pets.size # => 0
425
+ # person.pets # => []
426
+ #
427
+ # Pet.find(1, 2, 3)
428
+ # # => [
429
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>,
430
+ # # #<Pet id: 2, name: "Spook", person_id: nil>,
431
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: nil>
432
+ # # ]
433
+ #
434
+ # Both +has_many+ and <tt>has_many :through</tt> dependencies default to the
435
+ # +:delete_all+ strategy if the +:dependent+ option is set to +:destroy+.
436
+ # Records are not instantiated and callbacks will not be fired.
437
+ #
438
+ # class Person < ActiveRecord::Base
439
+ # has_many :pets, dependent: :destroy
440
+ # end
441
+ #
442
+ # person.pets.size # => 3
443
+ # person.pets
444
+ # # => [
445
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
446
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
447
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
448
+ # # ]
449
+ #
450
+ # person.pets.delete_all
451
+ #
452
+ # Pet.find(1, 2, 3)
453
+ # # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
454
+ #
455
+ # If it is set to <tt>:delete_all</tt>, all the objects are deleted
456
+ # *without* calling their +destroy+ method.
457
+ #
458
+ # class Person < ActiveRecord::Base
459
+ # has_many :pets, dependent: :delete_all
460
+ # end
461
+ #
462
+ # person.pets.size # => 3
463
+ # person.pets
464
+ # # => [
465
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
466
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
467
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
468
+ # # ]
469
+ #
470
+ # person.pets.delete_all
471
+ #
472
+ # Pet.find(1, 2, 3)
473
+ # # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
474
+ def delete_all(dependent = nil)
475
+ @association.delete_all(dependent).tap { reset_scope }
476
+ end
477
+
478
+ # Deletes the records of the collection directly from the database
479
+ # ignoring the +:dependent+ option. Records are instantiated and it
480
+ # invokes +before_remove+, +after_remove+, +before_destroy+, and
481
+ # +after_destroy+ callbacks.
482
+ #
483
+ # class Person < ActiveRecord::Base
484
+ # has_many :pets
485
+ # end
486
+ #
487
+ # person.pets.size # => 3
488
+ # person.pets
489
+ # # => [
490
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
491
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
492
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
493
+ # # ]
494
+ #
495
+ # person.pets.destroy_all
496
+ #
497
+ # person.pets.size # => 0
498
+ # person.pets # => []
499
+ #
500
+ # Pet.find(1) # => Couldn't find Pet with id=1
501
+ def destroy_all
502
+ @association.destroy_all.tap { reset_scope }
503
+ end
504
+
505
+ # Deletes the +records+ supplied from the collection according to the strategy
506
+ # specified by the +:dependent+ option. If no +:dependent+ option is given,
507
+ # then it will follow the default strategy. Returns an array with the
508
+ # deleted records.
509
+ #
510
+ # For <tt>has_many :through</tt> associations, the default deletion strategy is
511
+ # +:delete_all+.
512
+ #
513
+ # For +has_many+ associations, the default deletion strategy is +:nullify+.
514
+ # This sets the foreign keys to +NULL+.
515
+ #
516
+ # class Person < ActiveRecord::Base
517
+ # has_many :pets # dependent: :nullify option by default
518
+ # end
519
+ #
520
+ # person.pets.size # => 3
521
+ # person.pets
522
+ # # => [
523
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
524
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
525
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
526
+ # # ]
527
+ #
528
+ # person.pets.delete(Pet.find(1))
529
+ # # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
530
+ #
531
+ # person.pets.size # => 2
532
+ # person.pets
533
+ # # => [
534
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
535
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
536
+ # # ]
537
+ #
538
+ # Pet.find(1)
539
+ # # => #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>
540
+ #
541
+ # If it is set to <tt>:destroy</tt> all the +records+ are removed by calling
542
+ # their +destroy+ method. See +destroy+ for more information.
543
+ #
544
+ # class Person < ActiveRecord::Base
545
+ # has_many :pets, dependent: :destroy
546
+ # end
547
+ #
548
+ # person.pets.size # => 3
549
+ # person.pets
550
+ # # => [
551
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
552
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
553
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
554
+ # # ]
555
+ #
556
+ # person.pets.delete(Pet.find(1), Pet.find(3))
557
+ # # => [
558
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
559
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
560
+ # # ]
561
+ #
562
+ # person.pets.size # => 1
563
+ # person.pets
564
+ # # => [#<Pet id: 2, name: "Spook", person_id: 1>]
565
+ #
566
+ # Pet.find(1, 3)
567
+ # # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 3)
568
+ #
569
+ # If it is set to <tt>:delete_all</tt>, all the +records+ are deleted
570
+ # *without* calling their +destroy+ method.
571
+ #
572
+ # class Person < ActiveRecord::Base
573
+ # has_many :pets, dependent: :delete_all
574
+ # end
575
+ #
576
+ # person.pets.size # => 3
577
+ # person.pets
578
+ # # => [
579
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
580
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
581
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
582
+ # # ]
583
+ #
584
+ # person.pets.delete(Pet.find(1))
585
+ # # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
586
+ #
587
+ # person.pets.size # => 2
588
+ # person.pets
589
+ # # => [
590
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
591
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
592
+ # # ]
593
+ #
594
+ # Pet.find(1)
595
+ # # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=1
596
+ #
597
+ # You can pass +Integer+ or +String+ values, it finds the records
598
+ # responding to the +id+ and executes delete on them.
599
+ #
600
+ # class Person < ActiveRecord::Base
601
+ # has_many :pets
602
+ # end
603
+ #
604
+ # person.pets.size # => 3
605
+ # person.pets
606
+ # # => [
607
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
608
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
609
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
610
+ # # ]
611
+ #
612
+ # person.pets.delete("1")
613
+ # # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
614
+ #
615
+ # person.pets.delete(2, 3)
616
+ # # => [
617
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
618
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
619
+ # # ]
620
+ def delete(*records)
621
+ @association.delete(*records).tap { reset_scope }
622
+ end
623
+
624
+ # Destroys the +records+ supplied and removes them from the collection.
625
+ # This method will _always_ remove record from the database ignoring
626
+ # the +:dependent+ option. Returns an array with the removed records.
627
+ #
628
+ # class Person < ActiveRecord::Base
629
+ # has_many :pets
630
+ # end
631
+ #
632
+ # person.pets.size # => 3
633
+ # person.pets
634
+ # # => [
635
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
636
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
637
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
638
+ # # ]
639
+ #
640
+ # person.pets.destroy(Pet.find(1))
641
+ # # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
642
+ #
643
+ # person.pets.size # => 2
644
+ # person.pets
645
+ # # => [
646
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
647
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
648
+ # # ]
649
+ #
650
+ # person.pets.destroy(Pet.find(2), Pet.find(3))
651
+ # # => [
652
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
653
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
654
+ # # ]
655
+ #
656
+ # person.pets.size # => 0
657
+ # person.pets # => []
658
+ #
659
+ # Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
660
+ #
661
+ # You can pass +Integer+ or +String+ values, it finds the records
662
+ # responding to the +id+ and then deletes them from the database.
663
+ #
664
+ # person.pets.size # => 3
665
+ # person.pets
666
+ # # => [
667
+ # # #<Pet id: 4, name: "Benny", person_id: 1>,
668
+ # # #<Pet id: 5, name: "Brain", person_id: 1>,
669
+ # # #<Pet id: 6, name: "Boss", person_id: 1>
670
+ # # ]
671
+ #
672
+ # person.pets.destroy("4")
673
+ # # => #<Pet id: 4, name: "Benny", person_id: 1>
674
+ #
675
+ # person.pets.size # => 2
676
+ # person.pets
677
+ # # => [
678
+ # # #<Pet id: 5, name: "Brain", person_id: 1>,
679
+ # # #<Pet id: 6, name: "Boss", person_id: 1>
680
+ # # ]
681
+ #
682
+ # person.pets.destroy(5, 6)
683
+ # # => [
684
+ # # #<Pet id: 5, name: "Brain", person_id: 1>,
685
+ # # #<Pet id: 6, name: "Boss", person_id: 1>
686
+ # # ]
687
+ #
688
+ # person.pets.size # => 0
689
+ # person.pets # => []
690
+ #
691
+ # Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (4, 5, 6)
692
+ def destroy(*records)
693
+ @association.destroy(*records).tap { reset_scope }
694
+ end
695
+
696
+ ##
697
+ # :method: distinct
698
+ #
699
+ # :call-seq:
700
+ # distinct(value = true)
701
+ #
702
+ # Specifies whether the records should be unique or not.
703
+ #
704
+ # class Person < ActiveRecord::Base
705
+ # has_many :pets
706
+ # end
707
+ #
708
+ # person.pets.select(:name)
709
+ # # => [
710
+ # # #<Pet name: "Fancy-Fancy">,
711
+ # # #<Pet name: "Fancy-Fancy">
712
+ # # ]
713
+ #
714
+ # person.pets.select(:name).distinct
715
+ # # => [#<Pet name: "Fancy-Fancy">]
716
+ #
717
+ # person.pets.select(:name).distinct.distinct(false)
718
+ # # => [
719
+ # # #<Pet name: "Fancy-Fancy">,
720
+ # # #<Pet name: "Fancy-Fancy">
721
+ # # ]
722
+
723
+ #--
724
+ def calculate(operation, column_name)
725
+ null_scope? ? scope.calculate(operation, column_name) : super
726
+ end
727
+
728
+ def pluck(*column_names)
729
+ null_scope? ? scope.pluck(*column_names) : super
730
+ end
731
+
732
+ ##
733
+ # :method: count
734
+ #
735
+ # :call-seq:
736
+ # count(column_name = nil, &block)
737
+ #
738
+ # Count all records.
739
+ #
740
+ # class Person < ActiveRecord::Base
741
+ # has_many :pets
742
+ # end
743
+ #
744
+ # # This will perform the count using SQL.
745
+ # person.pets.count # => 3
746
+ # person.pets
747
+ # # => [
748
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
749
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
750
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
751
+ # # ]
752
+ #
753
+ # Passing a block will select all of a person's pets in SQL and then
754
+ # perform the count using Ruby.
755
+ #
756
+ # person.pets.count { |pet| pet.name.include?('-') } # => 2
757
+
758
+ # Returns the size of the collection. If the collection hasn't been loaded,
759
+ # it executes a <tt>SELECT COUNT(*)</tt> query. Else it calls <tt>collection.size</tt>.
760
+ #
761
+ # If the collection has been already loaded +size+ and +length+ are
762
+ # equivalent. If not and you are going to need the records anyway
763
+ # +length+ will take one less query. Otherwise +size+ is more efficient.
764
+ #
765
+ # class Person < ActiveRecord::Base
766
+ # has_many :pets
767
+ # end
768
+ #
769
+ # person.pets.size # => 3
770
+ # # executes something like SELECT COUNT(*) FROM "pets" WHERE "pets"."person_id" = 1
771
+ #
772
+ # person.pets # This will execute a SELECT * FROM query
773
+ # # => [
774
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
775
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
776
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
777
+ # # ]
778
+ #
779
+ # person.pets.size # => 3
780
+ # # Because the collection is already loaded, this will behave like
781
+ # # collection.size and no SQL count query is executed.
782
+ def size
783
+ @association.size
784
+ end
785
+
786
+ ##
787
+ # :method: length
788
+ #
789
+ # :call-seq:
790
+ # length()
791
+ #
792
+ # Returns the size of the collection calling +size+ on the target.
793
+ # If the collection has been already loaded, +length+ and +size+ are
794
+ # equivalent. If not and you are going to need the records anyway this
795
+ # method will take one less query. Otherwise +size+ is more efficient.
796
+ #
797
+ # class Person < ActiveRecord::Base
798
+ # has_many :pets
799
+ # end
800
+ #
801
+ # person.pets.length # => 3
802
+ # # executes something like SELECT "pets".* FROM "pets" WHERE "pets"."person_id" = 1
803
+ #
804
+ # # Because the collection is loaded, you can
805
+ # # call the collection with no additional queries:
806
+ # person.pets
807
+ # # => [
808
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
809
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
810
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
811
+ # # ]
812
+
813
+ # Returns +true+ if the collection is empty. If the collection has been
814
+ # loaded it is equivalent
815
+ # to <tt>collection.size.zero?</tt>. If the collection has not been loaded,
816
+ # it is equivalent to <tt>!collection.exists?</tt>. If the collection has
817
+ # not already been loaded and you are going to fetch the records anyway it
818
+ # is better to check <tt>collection.load.empty?</tt>.
819
+ #
820
+ # class Person < ActiveRecord::Base
821
+ # has_many :pets
822
+ # end
823
+ #
824
+ # person.pets.count # => 1
825
+ # person.pets.empty? # => false
826
+ #
827
+ # person.pets.delete_all
828
+ #
829
+ # person.pets.count # => 0
830
+ # person.pets.empty? # => true
831
+ def empty?
832
+ @association.empty?
833
+ end
834
+
835
+ ##
836
+ # :method: any?
837
+ #
838
+ # :call-seq:
839
+ # any?()
840
+ #
841
+ # Returns +true+ if the collection is not empty.
842
+ #
843
+ # class Person < ActiveRecord::Base
844
+ # has_many :pets
845
+ # end
846
+ #
847
+ # person.pets.count # => 0
848
+ # person.pets.any? # => false
849
+ #
850
+ # person.pets << Pet.new(name: 'Snoop')
851
+ # person.pets.count # => 1
852
+ # person.pets.any? # => true
853
+ #
854
+ # Calling it without a block when the collection is not yet
855
+ # loaded is equivalent to <tt>collection.exists?</tt>.
856
+ # If you're going to load the collection anyway, it is better
857
+ # to call <tt>collection.load.any?</tt> to avoid an extra query.
858
+ #
859
+ # You can also pass a +block+ to define criteria. The behavior
860
+ # is the same, it returns true if the collection based on the
861
+ # criteria is not empty.
862
+ #
863
+ # person.pets
864
+ # # => [#<Pet name: "Snoop", group: "dogs">]
865
+ #
866
+ # person.pets.any? do |pet|
867
+ # pet.group == 'cats'
868
+ # end
869
+ # # => false
870
+ #
871
+ # person.pets.any? do |pet|
872
+ # pet.group == 'dogs'
873
+ # end
874
+ # # => true
875
+
876
+ ##
877
+ # :method: many?
878
+ #
879
+ # :call-seq:
880
+ # many?()
881
+ #
882
+ # Returns true if the collection has more than one record.
883
+ # Equivalent to <tt>collection.size > 1</tt>.
884
+ #
885
+ # class Person < ActiveRecord::Base
886
+ # has_many :pets
887
+ # end
888
+ #
889
+ # person.pets.count # => 1
890
+ # person.pets.many? # => false
891
+ #
892
+ # person.pets << Pet.new(name: 'Snoopy')
893
+ # person.pets.count # => 2
894
+ # person.pets.many? # => true
895
+ #
896
+ # You can also pass a +block+ to define criteria. The
897
+ # behavior is the same, it returns true if the collection
898
+ # based on the criteria has more than one record.
899
+ #
900
+ # person.pets
901
+ # # => [
902
+ # # #<Pet name: "Gorby", group: "cats">,
903
+ # # #<Pet name: "Puff", group: "cats">,
904
+ # # #<Pet name: "Snoop", group: "dogs">
905
+ # # ]
906
+ #
907
+ # person.pets.many? do |pet|
908
+ # pet.group == 'dogs'
909
+ # end
910
+ # # => false
911
+ #
912
+ # person.pets.many? do |pet|
913
+ # pet.group == 'cats'
914
+ # end
915
+ # # => true
916
+
917
+ # Returns +true+ if the given +record+ is present in the collection.
918
+ #
919
+ # class Person < ActiveRecord::Base
920
+ # has_many :pets
921
+ # end
922
+ #
923
+ # person.pets # => [#<Pet id: 20, name: "Snoop">]
924
+ #
925
+ # person.pets.include?(Pet.find(20)) # => true
926
+ # person.pets.include?(Pet.find(21)) # => false
927
+ def include?(record)
928
+ !!@association.include?(record)
929
+ end
930
+
931
+ # Returns the association object for the collection.
932
+ #
933
+ # class Person < ActiveRecord::Base
934
+ # has_many :pets
935
+ # end
936
+ #
937
+ # person.pets.proxy_association
938
+ # # => #<ActiveRecord::Associations::HasManyAssociation owner="#<Person:0x00>">
939
+ #
940
+ # Returns the same object as <tt>person.association(:pets)</tt>,
941
+ # allowing you to make calls like <tt>person.pets.proxy_association.owner</tt>.
942
+ #
943
+ # See Associations::ClassMethods@Association+extensions for more.
944
+ def proxy_association
945
+ @association
946
+ end
947
+
948
+ # Returns a Relation object for the records in this association
949
+ def scope
950
+ @scope ||= @association.scope
951
+ end
952
+
953
+ # Equivalent to <tt>Array#==</tt>. Returns +true+ if the two arrays
954
+ # contain the same number of elements and if each element is equal
955
+ # to the corresponding element in the +other+ array, otherwise returns
956
+ # +false+.
957
+ #
958
+ # class Person < ActiveRecord::Base
959
+ # has_many :pets
960
+ # end
961
+ #
962
+ # person.pets
963
+ # # => [
964
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
965
+ # # #<Pet id: 2, name: "Spook", person_id: 1>
966
+ # # ]
967
+ #
968
+ # other = person.pets.to_ary
969
+ #
970
+ # person.pets == other
971
+ # # => true
972
+ #
973
+ #
974
+ # Note that unpersisted records can still be seen as equal:
975
+ #
976
+ # other = [Pet.new(id: 1), Pet.new(id: 2)]
977
+ #
978
+ # person.pets == other
979
+ # # => true
980
+ def ==(other)
981
+ load_target == other
982
+ end
983
+
984
+ ##
985
+ # :method: to_ary
986
+ #
987
+ # :call-seq:
988
+ # to_ary()
989
+ #
990
+ # Returns a new array of objects from the collection. If the collection
991
+ # hasn't been loaded, it fetches the records from the database.
992
+ #
993
+ # class Person < ActiveRecord::Base
994
+ # has_many :pets
995
+ # end
996
+ #
997
+ # person.pets
998
+ # # => [
999
+ # # #<Pet id: 4, name: "Benny", person_id: 1>,
1000
+ # # #<Pet id: 5, name: "Brain", person_id: 1>,
1001
+ # # #<Pet id: 6, name: "Boss", person_id: 1>
1002
+ # # ]
1003
+ #
1004
+ # other_pets = person.pets.to_ary
1005
+ # # => [
1006
+ # # #<Pet id: 4, name: "Benny", person_id: 1>,
1007
+ # # #<Pet id: 5, name: "Brain", person_id: 1>,
1008
+ # # #<Pet id: 6, name: "Boss", person_id: 1>
1009
+ # # ]
1010
+ #
1011
+ # other_pets.replace([Pet.new(name: 'BooGoo')])
1012
+ #
1013
+ # other_pets
1014
+ # # => [#<Pet id: nil, name: "BooGoo", person_id: 1>]
1015
+ #
1016
+ # person.pets
1017
+ # # This is not affected by replace
1018
+ # # => [
1019
+ # # #<Pet id: 4, name: "Benny", person_id: 1>,
1020
+ # # #<Pet id: 5, name: "Brain", person_id: 1>,
1021
+ # # #<Pet id: 6, name: "Boss", person_id: 1>
1022
+ # # ]
1023
+
1024
+ def records # :nodoc:
1025
+ load_target
1026
+ end
1027
+
1028
+ # Adds one or more +records+ to the collection by setting their foreign keys
1029
+ # to the association's primary key. Since <tt><<</tt> flattens its argument list and
1030
+ # inserts each record, +push+ and +concat+ behave identically. Returns +self+
1031
+ # so several appends may be chained together.
1032
+ #
1033
+ # class Person < ActiveRecord::Base
1034
+ # has_many :pets
1035
+ # end
1036
+ #
1037
+ # person.pets.size # => 0
1038
+ # person.pets << Pet.new(name: 'Fancy-Fancy')
1039
+ # person.pets << [Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo')]
1040
+ # person.pets.size # => 3
1041
+ #
1042
+ # person.id # => 1
1043
+ # person.pets
1044
+ # # => [
1045
+ # # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
1046
+ # # #<Pet id: 2, name: "Spook", person_id: 1>,
1047
+ # # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
1048
+ # # ]
1049
+ def <<(*records)
1050
+ proxy_association.concat(records) && self
1051
+ end
1052
+ alias_method :push, :<<
1053
+ alias_method :append, :<<
1054
+ alias_method :concat, :<<
1055
+
1056
+ def prepend(*args) # :nodoc:
1057
+ raise NoMethodError, "prepend on association is not defined. Please use <<, push or append"
1058
+ end
1059
+
1060
+ # Equivalent to +delete_all+. The difference is that returns +self+, instead
1061
+ # of an array with the deleted objects, so methods can be chained. See
1062
+ # +delete_all+ for more information.
1063
+ # Note that because +delete_all+ removes records by directly
1064
+ # running an SQL query into the database, the +updated_at+ column of
1065
+ # the object is not changed.
1066
+ def clear
1067
+ delete_all
1068
+ self
1069
+ end
1070
+
1071
+ # Reloads the collection from the database. Returns +self+.
1072
+ #
1073
+ # class Person < ActiveRecord::Base
1074
+ # has_many :pets
1075
+ # end
1076
+ #
1077
+ # person.pets # fetches pets from the database
1078
+ # # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
1079
+ #
1080
+ # person.pets # uses the pets cache
1081
+ # # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
1082
+ #
1083
+ # person.pets.reload # fetches pets from the database
1084
+ # # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
1085
+ def reload
1086
+ proxy_association.reload(true)
1087
+ reset_scope
1088
+ end
1089
+
1090
+ # Unloads the association. Returns +self+.
1091
+ #
1092
+ # class Person < ActiveRecord::Base
1093
+ # has_many :pets
1094
+ # end
1095
+ #
1096
+ # person.pets # fetches pets from the database
1097
+ # # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
1098
+ #
1099
+ # person.pets # uses the pets cache
1100
+ # # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
1101
+ #
1102
+ # person.pets.reset # clears the pets cache
1103
+ #
1104
+ # person.pets # fetches pets from the database
1105
+ # # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
1106
+ def reset
1107
+ proxy_association.reset
1108
+ proxy_association.reset_scope
1109
+ reset_scope
1110
+ end
1111
+
1112
+ def reset_scope # :nodoc:
1113
+ @offsets = @take = nil
1114
+ @scope = nil
1115
+ self
1116
+ end
1117
+
1118
+ def inspect # :nodoc:
1119
+ load_target if find_from_target?
1120
+ super
1121
+ end
1122
+
1123
+ def pretty_print(pp) # :nodoc:
1124
+ load_target if find_from_target?
1125
+ super
1126
+ end
1127
+
1128
+ delegate_methods = [
1129
+ QueryMethods,
1130
+ SpawnMethods,
1131
+ ].flat_map { |klass|
1132
+ klass.public_instance_methods(false)
1133
+ } - self.public_instance_methods(false) - [:select] + [
1134
+ :scoping, :values, :insert, :insert_all, :insert!, :insert_all!, :upsert, :upsert_all, :load_async
1135
+ ]
1136
+
1137
+ delegate(*delegate_methods, to: :scope)
1138
+
1139
+ private
1140
+ def find_nth_with_limit(index, limit)
1141
+ load_target if find_from_target?
1142
+ super
1143
+ end
1144
+
1145
+ def find_nth_from_last(index)
1146
+ load_target if find_from_target?
1147
+ super
1148
+ end
1149
+
1150
+ def null_scope?
1151
+ @association.null_scope?
1152
+ end
1153
+
1154
+ def find_from_target?
1155
+ @association.find_from_target?
1156
+ end
1157
+
1158
+ def exec_queries
1159
+ load_target
1160
+ end
1161
+ end
1162
+ end
1163
+ end