activerecord 5.0.6 → 6.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (358) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +638 -2023
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +8 -6
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/aggregations.rb +249 -246
  8. data/lib/active_record/association_relation.rb +24 -13
  9. data/lib/active_record/associations/alias_tracker.rb +24 -33
  10. data/lib/active_record/associations/association.rb +119 -56
  11. data/lib/active_record/associations/association_scope.rb +94 -94
  12. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +18 -25
  15. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  16. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
  18. data/lib/active_record/associations/builder/has_many.rb +4 -0
  19. data/lib/active_record/associations/builder/has_one.rb +37 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  21. data/lib/active_record/associations/collection_association.rb +80 -252
  22. data/lib/active_record/associations/collection_proxy.rb +158 -121
  23. data/lib/active_record/associations/foreign_association.rb +9 -0
  24. data/lib/active_record/associations/has_many_association.rb +23 -29
  25. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  26. data/lib/active_record/associations/has_one_association.rb +59 -54
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  31. data/lib/active_record/associations/join_dependency.rb +134 -176
  32. data/lib/active_record/associations/preloader/association.rb +84 -125
  33. data/lib/active_record/associations/preloader/through_association.rb +82 -75
  34. data/lib/active_record/associations/preloader.rb +90 -102
  35. data/lib/active_record/associations/singular_association.rb +12 -45
  36. data/lib/active_record/associations/through_association.rb +26 -14
  37. data/lib/active_record/associations.rb +1603 -1592
  38. data/lib/active_record/attribute_assignment.rb +54 -60
  39. data/lib/active_record/attribute_decorators.rb +38 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  42. data/lib/active_record/attribute_methods/primary_key.rb +86 -91
  43. data/lib/active_record/attribute_methods/query.rb +4 -3
  44. data/lib/active_record/attribute_methods/read.rb +21 -49
  45. data/lib/active_record/attribute_methods/serialization.rb +30 -7
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
  47. data/lib/active_record/attribute_methods/write.rb +35 -33
  48. data/lib/active_record/attribute_methods.rb +66 -106
  49. data/lib/active_record/attributes.rb +38 -24
  50. data/lib/active_record/autosave_association.rb +53 -32
  51. data/lib/active_record/base.rb +27 -24
  52. data/lib/active_record/callbacks.rb +63 -33
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -11
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
  68. data/lib/active_record/connection_adapters/column.rb +41 -13
  69. data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  71. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  98. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
  116. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
  126. data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
  127. data/lib/active_record/connection_handling.rb +159 -40
  128. data/lib/active_record/core.rb +202 -162
  129. data/lib/active_record/counter_cache.rb +57 -28
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -86
  136. data/lib/active_record/enum.rb +60 -23
  137. data/lib/active_record/errors.rb +114 -18
  138. data/lib/active_record/explain.rb +4 -3
  139. data/lib/active_record/explain_registry.rb +3 -1
  140. data/lib/active_record/explain_subscriber.rb +9 -4
  141. data/lib/active_record/fixture_set/file.rb +13 -8
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +195 -502
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +151 -97
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +116 -25
  151. data/lib/active_record/internal_metadata.rb +15 -18
  152. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  153. data/lib/active_record/locking/optimistic.rb +78 -87
  154. data/lib/active_record/locking/pessimistic.rb +18 -6
  155. data/lib/active_record/log_subscriber.rb +48 -29
  156. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  157. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/migration/command_recorder.rb +143 -97
  160. data/lib/active_record/migration/compatibility.rb +174 -56
  161. data/lib/active_record/migration/join_table.rb +8 -6
  162. data/lib/active_record/migration.rb +367 -300
  163. data/lib/active_record/model_schema.rb +145 -139
  164. data/lib/active_record/nested_attributes.rb +214 -201
  165. data/lib/active_record/no_touching.rb +10 -1
  166. data/lib/active_record/null_relation.rb +13 -34
  167. data/lib/active_record/persistence.rb +442 -72
  168. data/lib/active_record/query_cache.rb +15 -14
  169. data/lib/active_record/querying.rb +36 -23
  170. data/lib/active_record/railtie.rb +128 -36
  171. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  172. data/lib/active_record/railties/console_sandbox.rb +2 -0
  173. data/lib/active_record/railties/controller_runtime.rb +34 -33
  174. data/lib/active_record/railties/databases.rake +309 -177
  175. data/lib/active_record/readonly_attributes.rb +5 -4
  176. data/lib/active_record/reflection.rb +211 -249
  177. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  178. data/lib/active_record/relation/batches.rb +99 -52
  179. data/lib/active_record/relation/calculations.rb +211 -172
  180. data/lib/active_record/relation/delegation.rb +67 -65
  181. data/lib/active_record/relation/finder_methods.rb +208 -247
  182. data/lib/active_record/relation/from_clause.rb +2 -8
  183. data/lib/active_record/relation/merger.rb +78 -61
  184. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  185. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  186. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  187. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  188. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  189. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  190. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  191. data/lib/active_record/relation/predicate_builder.rb +86 -104
  192. data/lib/active_record/relation/query_attribute.rb +33 -2
  193. data/lib/active_record/relation/query_methods.rb +458 -329
  194. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  195. data/lib/active_record/relation/spawn_methods.rb +8 -7
  196. data/lib/active_record/relation/where_clause.rb +111 -95
  197. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  198. data/lib/active_record/relation.rb +429 -318
  199. data/lib/active_record/result.rb +69 -39
  200. data/lib/active_record/runtime_registry.rb +5 -3
  201. data/lib/active_record/sanitization.rb +83 -99
  202. data/lib/active_record/schema.rb +7 -14
  203. data/lib/active_record/schema_dumper.rb +71 -69
  204. data/lib/active_record/schema_migration.rb +15 -5
  205. data/lib/active_record/scoping/default.rb +93 -95
  206. data/lib/active_record/scoping/named.rb +45 -25
  207. data/lib/active_record/scoping.rb +20 -19
  208. data/lib/active_record/secure_token.rb +4 -2
  209. data/lib/active_record/serialization.rb +2 -0
  210. data/lib/active_record/statement_cache.rb +63 -28
  211. data/lib/active_record/store.rb +121 -41
  212. data/lib/active_record/suppressor.rb +4 -1
  213. data/lib/active_record/table_metadata.rb +26 -20
  214. data/lib/active_record/tasks/database_tasks.rb +276 -85
  215. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
  216. data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
  217. data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
  218. data/lib/active_record/test_databases.rb +23 -0
  219. data/lib/active_record/test_fixtures.rb +224 -0
  220. data/lib/active_record/timestamp.rb +70 -35
  221. data/lib/active_record/touch_later.rb +7 -4
  222. data/lib/active_record/transactions.rb +133 -149
  223. data/lib/active_record/translation.rb +3 -1
  224. data/lib/active_record/type/adapter_specific_registry.rb +44 -45
  225. data/lib/active_record/type/date.rb +2 -0
  226. data/lib/active_record/type/date_time.rb +2 -0
  227. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  228. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  229. data/lib/active_record/type/internal/timezone.rb +2 -0
  230. data/lib/active_record/type/json.rb +30 -0
  231. data/lib/active_record/type/serialized.rb +16 -8
  232. data/lib/active_record/type/text.rb +11 -0
  233. data/lib/active_record/type/time.rb +2 -1
  234. data/lib/active_record/type/type_map.rb +13 -15
  235. data/lib/active_record/type/unsigned_integer.rb +17 -0
  236. data/lib/active_record/type.rb +23 -17
  237. data/lib/active_record/type_caster/connection.rb +17 -12
  238. data/lib/active_record/type_caster/map.rb +5 -4
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/validations/absence.rb +2 -0
  241. data/lib/active_record/validations/associated.rb +3 -1
  242. data/lib/active_record/validations/length.rb +2 -0
  243. data/lib/active_record/validations/presence.rb +4 -2
  244. data/lib/active_record/validations/uniqueness.rb +29 -42
  245. data/lib/active_record/validations.rb +7 -4
  246. data/lib/active_record/version.rb +3 -1
  247. data/lib/active_record.rb +36 -22
  248. data/lib/arel/alias_predication.rb +9 -0
  249. data/lib/arel/attributes/attribute.rb +37 -0
  250. data/lib/arel/attributes.rb +22 -0
  251. data/lib/arel/collectors/bind.rb +24 -0
  252. data/lib/arel/collectors/composite.rb +31 -0
  253. data/lib/arel/collectors/plain_string.rb +20 -0
  254. data/lib/arel/collectors/sql_string.rb +20 -0
  255. data/lib/arel/collectors/substitute_binds.rb +28 -0
  256. data/lib/arel/crud.rb +42 -0
  257. data/lib/arel/delete_manager.rb +18 -0
  258. data/lib/arel/errors.rb +9 -0
  259. data/lib/arel/expressions.rb +29 -0
  260. data/lib/arel/factory_methods.rb +49 -0
  261. data/lib/arel/insert_manager.rb +49 -0
  262. data/lib/arel/math.rb +45 -0
  263. data/lib/arel/nodes/and.rb +32 -0
  264. data/lib/arel/nodes/ascending.rb +23 -0
  265. data/lib/arel/nodes/binary.rb +52 -0
  266. data/lib/arel/nodes/bind_param.rb +36 -0
  267. data/lib/arel/nodes/case.rb +55 -0
  268. data/lib/arel/nodes/casted.rb +50 -0
  269. data/lib/arel/nodes/comment.rb +29 -0
  270. data/lib/arel/nodes/count.rb +12 -0
  271. data/lib/arel/nodes/delete_statement.rb +45 -0
  272. data/lib/arel/nodes/descending.rb +23 -0
  273. data/lib/arel/nodes/equality.rb +18 -0
  274. data/lib/arel/nodes/extract.rb +24 -0
  275. data/lib/arel/nodes/false.rb +16 -0
  276. data/lib/arel/nodes/full_outer_join.rb +8 -0
  277. data/lib/arel/nodes/function.rb +44 -0
  278. data/lib/arel/nodes/grouping.rb +8 -0
  279. data/lib/arel/nodes/in.rb +8 -0
  280. data/lib/arel/nodes/infix_operation.rb +80 -0
  281. data/lib/arel/nodes/inner_join.rb +8 -0
  282. data/lib/arel/nodes/insert_statement.rb +37 -0
  283. data/lib/arel/nodes/join_source.rb +20 -0
  284. data/lib/arel/nodes/matches.rb +18 -0
  285. data/lib/arel/nodes/named_function.rb +23 -0
  286. data/lib/arel/nodes/node.rb +50 -0
  287. data/lib/arel/nodes/node_expression.rb +13 -0
  288. data/lib/arel/nodes/outer_join.rb +8 -0
  289. data/lib/arel/nodes/over.rb +15 -0
  290. data/lib/arel/nodes/regexp.rb +16 -0
  291. data/lib/arel/nodes/right_outer_join.rb +8 -0
  292. data/lib/arel/nodes/select_core.rb +67 -0
  293. data/lib/arel/nodes/select_statement.rb +41 -0
  294. data/lib/arel/nodes/sql_literal.rb +16 -0
  295. data/lib/arel/nodes/string_join.rb +11 -0
  296. data/lib/arel/nodes/table_alias.rb +27 -0
  297. data/lib/arel/nodes/terminal.rb +16 -0
  298. data/lib/arel/nodes/true.rb +16 -0
  299. data/lib/arel/nodes/unary.rb +45 -0
  300. data/lib/arel/nodes/unary_operation.rb +20 -0
  301. data/lib/arel/nodes/unqualified_column.rb +22 -0
  302. data/lib/arel/nodes/update_statement.rb +41 -0
  303. data/lib/arel/nodes/values_list.rb +9 -0
  304. data/lib/arel/nodes/window.rb +126 -0
  305. data/lib/arel/nodes/with.rb +11 -0
  306. data/lib/arel/nodes.rb +68 -0
  307. data/lib/arel/order_predications.rb +13 -0
  308. data/lib/arel/predications.rb +257 -0
  309. data/lib/arel/select_manager.rb +271 -0
  310. data/lib/arel/table.rb +110 -0
  311. data/lib/arel/tree_manager.rb +72 -0
  312. data/lib/arel/update_manager.rb +34 -0
  313. data/lib/arel/visitors/depth_first.rb +204 -0
  314. data/lib/arel/visitors/dot.rb +297 -0
  315. data/lib/arel/visitors/ibm_db.rb +34 -0
  316. data/lib/arel/visitors/informix.rb +62 -0
  317. data/lib/arel/visitors/mssql.rb +157 -0
  318. data/lib/arel/visitors/mysql.rb +83 -0
  319. data/lib/arel/visitors/oracle.rb +159 -0
  320. data/lib/arel/visitors/oracle12.rb +66 -0
  321. data/lib/arel/visitors/postgresql.rb +110 -0
  322. data/lib/arel/visitors/sqlite.rb +39 -0
  323. data/lib/arel/visitors/to_sql.rb +889 -0
  324. data/lib/arel/visitors/visitor.rb +46 -0
  325. data/lib/arel/visitors/where_sql.rb +23 -0
  326. data/lib/arel/visitors.rb +20 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +58 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  332. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  334. data/lib/rails/generators/active_record/migration.rb +17 -2
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +133 -50
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  350. data/lib/active_record/attribute_set/builder.rb +0 -130
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/collection_cache_key.rb +0 -50
  353. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  354. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  355. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  356. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  357. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  358. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,4 +1,6 @@
1
- require 'active_support/per_thread_registry'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/per_thread_registry"
2
4
 
3
5
  module ActiveRecord
4
6
  module Scoping
@@ -9,33 +11,32 @@ module ActiveRecord
9
11
  include Named
10
12
  end
11
13
 
12
- module ClassMethods
13
- def current_scope(skip_inherited_scope = false) # :nodoc:
14
- ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope)
15
- end
16
-
17
- def current_scope=(scope) #:nodoc:
18
- ScopeRegistry.set_value_for(:current_scope, self, scope)
19
- end
20
-
14
+ module ClassMethods # :nodoc:
21
15
  # Collects attributes from scopes that should be applied when creating
22
16
  # an AR instance for the particular class this is called on.
23
- def scope_attributes # :nodoc:
17
+ def scope_attributes
24
18
  all.scope_for_create
25
19
  end
26
20
 
27
21
  # Are there attributes associated with this scope?
28
- def scope_attributes? # :nodoc:
22
+ def scope_attributes?
29
23
  current_scope
30
24
  end
25
+
26
+ def current_scope(skip_inherited_scope = false)
27
+ ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope)
28
+ end
29
+
30
+ def current_scope=(scope)
31
+ ScopeRegistry.set_value_for(:current_scope, self, scope)
32
+ end
31
33
  end
32
34
 
33
35
  def populate_with_current_scope_attributes # :nodoc:
34
36
  return unless self.class.scope_attributes?
35
37
 
36
- self.class.scope_attributes.each do |att,value|
37
- send("#{att}=", value) if respond_to?("#{att}=")
38
- end
38
+ attributes = self.class.scope_attributes
39
+ _assign_attributes(attributes) if attributes.any?
39
40
  end
40
41
 
41
42
  def initialize_internals_callback # :nodoc:
@@ -95,11 +96,11 @@ module ActiveRecord
95
96
 
96
97
  private
97
98
 
98
- def raise_invalid_scope_type!(scope_type)
99
- if !VALID_SCOPE_TYPES.include?(scope_type)
100
- raise ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry. Scope types must be included in VALID_SCOPE_TYPES"
99
+ def raise_invalid_scope_type!(scope_type)
100
+ if !VALID_SCOPE_TYPES.include?(scope_type)
101
+ raise ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry. Scope types must be included in VALID_SCOPE_TYPES"
102
+ end
101
103
  end
102
- end
103
104
  end
104
105
  end
105
106
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module SecureToken
3
5
  extend ActiveSupport::Concern
@@ -25,9 +27,9 @@ module ActiveRecord
25
27
  # You're encouraged to add a unique index in the database to deal with this even more unlikely scenario.
26
28
  def has_secure_token(attribute = :token)
27
29
  # Load securerandom only when has_secure_token is used.
28
- require 'active_support/core_ext/securerandom'
30
+ require "active_support/core_ext/securerandom"
29
31
  define_method("regenerate_#{attribute}") { update! attribute => self.class.generate_unique_secure_token }
30
- before_create { self.send("#{attribute}=", self.class.generate_unique_secure_token) unless self.send("#{attribute}?")}
32
+ before_create { send("#{attribute}=", self.class.generate_unique_secure_token) unless send("#{attribute}?") }
31
33
  end
32
34
 
33
35
  def generate_unique_secure_token
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord #:nodoc:
2
4
  # = Active Record \Serialization
3
5
  module Serialization
@@ -1,5 +1,6 @@
1
- module ActiveRecord
1
+ # frozen_string_literal: true
2
2
 
3
+ module ActiveRecord
3
4
  # Statement cache is used to cache a single statement in order to avoid creating the AST again.
4
5
  # Initializing the cache is done by passing the statement in the create block:
5
6
  #
@@ -8,12 +9,12 @@ module ActiveRecord
8
9
  # end
9
10
  #
10
11
  # The cached statement is executed by using the
11
- # [connection.execute]{rdoc-ref:ConnectionAdapters::DatabaseStatements#execute} method:
12
+ # {connection.execute}[rdoc-ref:ConnectionAdapters::DatabaseStatements#execute] method:
12
13
  #
13
- # cache.execute([], Book, Book.connection)
14
+ # cache.execute([], Book.connection)
14
15
  #
15
16
  # The relation returned by the block is cached, and for each
16
- # [execute]{rdoc-ref:ConnectionAdapters::DatabaseStatements#execute}
17
+ # {execute}[rdoc-ref:ConnectionAdapters::DatabaseStatements#execute]
17
18
  # call the cached relation gets duped. Database is queried when +to_a+ is called on the relation.
18
19
  #
19
20
  # If you want to cache the statement without the values you can use the +bind+ method of the
@@ -25,7 +26,7 @@ module ActiveRecord
25
26
  #
26
27
  # And pass the bind values as the first argument of +execute+ call.
27
28
  #
28
- # cache.execute(["my book"], Book, Book.connection)
29
+ # cache.execute(["my book"], Book.connection)
29
30
  class StatementCache # :nodoc:
30
31
  class Substitute; end # :nodoc:
31
32
 
@@ -40,28 +41,53 @@ module ActiveRecord
40
41
  end
41
42
 
42
43
  class PartialQuery < Query # :nodoc:
43
- def initialize values
44
+ def initialize(values)
44
45
  @values = values
45
- @indexes = values.each_with_index.find_all { |thing,i|
46
- Arel::Nodes::BindParam === thing
46
+ @indexes = values.each_with_index.find_all { |thing, i|
47
+ Substitute === thing
47
48
  }.map(&:last)
48
49
  end
49
50
 
50
51
  def sql_for(binds, connection)
51
52
  val = @values.dup
52
- binds = connection.prepare_binds_for_database(binds)
53
- @indexes.each { |i| val[i] = connection.quote(binds.shift) }
53
+ casted_binds = binds.map(&:value_for_database)
54
+ @indexes.each { |i| val[i] = connection.quote(casted_binds.shift) }
54
55
  val.join
55
56
  end
56
57
  end
57
58
 
58
- def self.query(visitor, ast)
59
- Query.new visitor.accept(ast, Arel::Collectors::SQLString.new).value
59
+ class PartialQueryCollector
60
+ def initialize
61
+ @parts = []
62
+ @binds = []
63
+ end
64
+
65
+ def <<(str)
66
+ @parts << str
67
+ self
68
+ end
69
+
70
+ def add_bind(obj)
71
+ @binds << obj
72
+ @parts << Substitute.new
73
+ self
74
+ end
75
+
76
+ def value
77
+ [@parts, @binds]
78
+ end
79
+ end
80
+
81
+ def self.query(sql)
82
+ Query.new(sql)
60
83
  end
61
84
 
62
- def self.partial_query(visitor, ast, collector)
63
- collected = visitor.accept(ast, collector).value
64
- PartialQuery.new collected
85
+ def self.partial_query(values)
86
+ PartialQuery.new(values)
87
+ end
88
+
89
+ def self.partial_query_collector
90
+ PartialQueryCollector.new
65
91
  end
66
92
 
67
93
  class Params # :nodoc:
@@ -70,7 +96,7 @@ module ActiveRecord
70
96
 
71
97
  class BindMap # :nodoc:
72
98
  def initialize(bound_attributes)
73
- @indexes = []
99
+ @indexes = []
74
100
  @bound_attributes = bound_attributes
75
101
 
76
102
  bound_attributes.each_with_index do |attr, i|
@@ -82,32 +108,41 @@ module ActiveRecord
82
108
 
83
109
  def bind(values)
84
110
  bas = @bound_attributes.dup
85
- @indexes.each_with_index { |offset,i| bas[offset] = bas[offset].with_cast_value(values[i]) }
111
+ @indexes.each_with_index { |offset, i| bas[offset] = bas[offset].with_cast_value(values[i]) }
86
112
  bas
87
113
  end
88
114
  end
89
115
 
90
- attr_reader :bind_map, :query_builder
91
-
92
- def self.create(connection, block = Proc.new)
93
- relation = block.call Params.new
94
- bind_map = BindMap.new relation.bound_attributes
95
- query_builder = connection.cacheable_query relation.arel
96
- new query_builder, bind_map
116
+ def self.create(connection, callable = nil, &block)
117
+ relation = (callable || block).call Params.new
118
+ query_builder, binds = connection.cacheable_query(self, relation.arel)
119
+ bind_map = BindMap.new(binds)
120
+ new(query_builder, bind_map, relation.klass)
97
121
  end
98
122
 
99
- def initialize(query_builder, bind_map)
123
+ def initialize(query_builder, bind_map, klass)
100
124
  @query_builder = query_builder
101
- @bind_map = bind_map
125
+ @bind_map = bind_map
126
+ @klass = klass
102
127
  end
103
128
 
104
- def execute(params, klass, connection, &block)
129
+ def execute(params, connection, &block)
105
130
  bind_values = bind_map.bind params
106
131
 
107
132
  sql = query_builder.sql_for bind_values, connection
108
133
 
109
134
  klass.find_by_sql(sql, bind_values, preparable: true, &block)
135
+ rescue ::RangeError
136
+ nil
110
137
  end
111
- alias :call :execute
138
+
139
+ def self.unsupported_value?(value)
140
+ case value
141
+ when NilClass, Array, Range, Hash, Relation, Base then true
142
+ end
143
+ end
144
+
145
+ private
146
+ attr_reader :query_builder, :bind_map, :klass
112
147
  end
113
148
  end
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/hash/indifferent_access'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/indifferent_access"
2
4
 
3
5
  module ActiveRecord
4
6
  # Store gives you a thin wrapper around serialize for the purpose of storing hashes in a single column.
@@ -9,14 +11,20 @@ module ActiveRecord
9
11
  # of the model. This is very helpful for easily exposing store keys to a form or elsewhere that's
10
12
  # already built around just accessing attributes on the model.
11
13
  #
14
+ # Every accessor comes with dirty tracking methods (+key_changed?+, +key_was+ and +key_change+) and
15
+ # methods to access the changes made during the last save (+saved_change_to_key?+, +saved_change_to_key+ and
16
+ # +key_before_last_save+).
17
+ #
18
+ # NOTE: There is no +key_will_change!+ method for accessors, use +store_will_change!+ instead.
19
+ #
12
20
  # Make sure that you declare the database column used for the serialized store as a text, so there's
13
21
  # plenty of room.
14
22
  #
15
23
  # You can set custom coder to encode/decode your serialized attributes to/from different formats.
16
24
  # JSON, YAML, Marshal are supported out of the box. Generally it can be any wrapper that provides +load+ and +dump+.
17
25
  #
18
- # NOTE: If you are using PostgreSQL specific columns like +hstore+ or +json+ there is no need for
19
- # the serialization provided by {.store}[rdoc-ref:rdoc-ref:ClassMethods#store].
26
+ # NOTE: If you are using structured database data types (eg. PostgreSQL +hstore+/+json+, or MySQL 5.7+
27
+ # +json+) there is no need for the serialization provided by {.store}[rdoc-ref:rdoc-ref:ClassMethods#store].
20
28
  # Simply use {.store_accessor}[rdoc-ref:ClassMethods#store_accessor] instead to generate
21
29
  # the accessor methods. Be aware that these columns use a string keyed hash and do not allow access
22
30
  # using a symbol.
@@ -29,24 +37,40 @@ module ActiveRecord
29
37
  #
30
38
  # class User < ActiveRecord::Base
31
39
  # store :settings, accessors: [ :color, :homepage ], coder: JSON
40
+ # store :parent, accessors: [ :name ], coder: JSON, prefix: true
41
+ # store :spouse, accessors: [ :name ], coder: JSON, prefix: :partner
42
+ # store :settings, accessors: [ :two_factor_auth ], suffix: true
43
+ # store :settings, accessors: [ :login_retry ], suffix: :config
32
44
  # end
33
45
  #
34
- # u = User.new(color: 'black', homepage: '37signals.com')
46
+ # u = User.new(color: 'black', homepage: '37signals.com', parent_name: 'Mary', partner_name: 'Lily')
35
47
  # u.color # Accessor stored attribute
48
+ # u.parent_name # Accessor stored attribute with prefix
49
+ # u.partner_name # Accessor stored attribute with custom prefix
50
+ # u.two_factor_auth_settings # Accessor stored attribute with suffix
51
+ # u.login_retry_config # Accessor stored attribute with custom suffix
36
52
  # u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
37
53
  #
38
54
  # # There is no difference between strings and symbols for accessing custom attributes
39
55
  # u.settings[:country] # => 'Denmark'
40
56
  # u.settings['country'] # => 'Denmark'
41
57
  #
58
+ # # Dirty tracking
59
+ # u.color = 'green'
60
+ # u.color_changed? # => true
61
+ # u.color_was # => 'black'
62
+ # u.color_change # => ['black', 'red']
63
+ #
42
64
  # # Add additional accessors to an existing store through store_accessor
43
65
  # class SuperUser < User
44
66
  # store_accessor :settings, :privileges, :servants
67
+ # store_accessor :parent, :birthday, prefix: true
68
+ # store_accessor :settings, :secret_question, suffix: :config
45
69
  # end
46
70
  #
47
71
  # The stored attribute names can be retrieved using {.stored_attributes}[rdoc-ref:rdoc-ref:ClassMethods#stored_attributes].
48
72
  #
49
- # User.stored_attributes[:settings] # [:color, :homepage]
73
+ # User.stored_attributes[:settings] # [:color, :homepage, :two_factor_auth, :login_retry]
50
74
  #
51
75
  # == Overwriting default accessors
52
76
  #
@@ -78,22 +102,79 @@ module ActiveRecord
78
102
 
79
103
  module ClassMethods
80
104
  def store(store_attribute, options = {})
81
- serialize store_attribute, IndifferentCoder.new(options[:coder])
82
- store_accessor(store_attribute, options[:accessors]) if options.has_key? :accessors
105
+ serialize store_attribute, IndifferentCoder.new(store_attribute, options[:coder])
106
+ store_accessor(store_attribute, options[:accessors], options.slice(:prefix, :suffix)) if options.has_key? :accessors
83
107
  end
84
108
 
85
- def store_accessor(store_attribute, *keys)
109
+ def store_accessor(store_attribute, *keys, prefix: nil, suffix: nil)
86
110
  keys = keys.flatten
87
111
 
112
+ accessor_prefix =
113
+ case prefix
114
+ when String, Symbol
115
+ "#{prefix}_"
116
+ when TrueClass
117
+ "#{store_attribute}_"
118
+ else
119
+ ""
120
+ end
121
+ accessor_suffix =
122
+ case suffix
123
+ when String, Symbol
124
+ "_#{suffix}"
125
+ when TrueClass
126
+ "_#{store_attribute}"
127
+ else
128
+ ""
129
+ end
130
+
88
131
  _store_accessors_module.module_eval do
89
132
  keys.each do |key|
90
- define_method("#{key}=") do |value|
133
+ accessor_key = "#{accessor_prefix}#{key}#{accessor_suffix}"
134
+
135
+ define_method("#{accessor_key}=") do |value|
91
136
  write_store_attribute(store_attribute, key, value)
92
137
  end
93
138
 
94
- define_method(key) do
139
+ define_method(accessor_key) do
95
140
  read_store_attribute(store_attribute, key)
96
141
  end
142
+
143
+ define_method("#{accessor_key}_changed?") do
144
+ return false unless attribute_changed?(store_attribute)
145
+ prev_store, new_store = changes[store_attribute]
146
+ prev_store&.dig(key) != new_store&.dig(key)
147
+ end
148
+
149
+ define_method("#{accessor_key}_change") do
150
+ return unless attribute_changed?(store_attribute)
151
+ prev_store, new_store = changes[store_attribute]
152
+ [prev_store&.dig(key), new_store&.dig(key)]
153
+ end
154
+
155
+ define_method("#{accessor_key}_was") do
156
+ return unless attribute_changed?(store_attribute)
157
+ prev_store, _new_store = changes[store_attribute]
158
+ prev_store&.dig(key)
159
+ end
160
+
161
+ define_method("saved_change_to_#{accessor_key}?") do
162
+ return false unless saved_change_to_attribute?(store_attribute)
163
+ prev_store, new_store = saved_change_to_attribute(store_attribute)
164
+ prev_store&.dig(key) != new_store&.dig(key)
165
+ end
166
+
167
+ define_method("saved_change_to_#{accessor_key}") do
168
+ return unless saved_change_to_attribute?(store_attribute)
169
+ prev_store, new_store = saved_change_to_attribute(store_attribute)
170
+ [prev_store&.dig(key), new_store&.dig(key)]
171
+ end
172
+
173
+ define_method("#{accessor_key}_before_last_save") do
174
+ return unless saved_change_to_attribute?(store_attribute)
175
+ prev_store, _new_store = saved_change_to_attribute(store_attribute)
176
+ prev_store&.dig(key)
177
+ end
97
178
  end
98
179
  end
99
180
 
@@ -114,27 +195,26 @@ module ActiveRecord
114
195
 
115
196
  def stored_attributes
116
197
  parent = superclass.respond_to?(:stored_attributes) ? superclass.stored_attributes : {}
117
- if self.local_stored_attributes
118
- parent.merge!(self.local_stored_attributes) { |k, a, b| a | b }
198
+ if local_stored_attributes
199
+ parent.merge!(local_stored_attributes) { |k, a, b| a | b }
119
200
  end
120
201
  parent
121
202
  end
122
203
  end
123
204
 
124
- protected
125
- def read_store_attribute(store_attribute, key)
205
+ private
206
+ def read_store_attribute(store_attribute, key) # :doc:
126
207
  accessor = store_accessor_for(store_attribute)
127
208
  accessor.read(self, store_attribute, key)
128
209
  end
129
210
 
130
- def write_store_attribute(store_attribute, key, value)
211
+ def write_store_attribute(store_attribute, key, value) # :doc:
131
212
  accessor = store_accessor_for(store_attribute)
132
213
  accessor.write(self, store_attribute, key, value)
133
214
  end
134
215
 
135
- private
136
216
  def store_accessor_for(store_attribute)
137
- type_for_attribute(store_attribute.to_s).accessor
217
+ type_for_attribute(store_attribute).accessor
138
218
  end
139
219
 
140
220
  class HashAccessor # :nodoc:
@@ -177,34 +257,34 @@ module ActiveRecord
177
257
  end
178
258
  end
179
259
 
180
- class IndifferentCoder # :nodoc:
181
- def initialize(coder_or_class_name)
182
- @coder =
183
- if coder_or_class_name.respond_to?(:load) && coder_or_class_name.respond_to?(:dump)
184
- coder_or_class_name
185
- else
186
- ActiveRecord::Coders::YAMLColumn.new(coder_or_class_name || Object)
187
- end
188
- end
260
+ class IndifferentCoder # :nodoc:
261
+ def initialize(attr_name, coder_or_class_name)
262
+ @coder =
263
+ if coder_or_class_name.respond_to?(:load) && coder_or_class_name.respond_to?(:dump)
264
+ coder_or_class_name
265
+ else
266
+ ActiveRecord::Coders::YAMLColumn.new(attr_name, coder_or_class_name || Object)
267
+ end
268
+ end
189
269
 
190
- def dump(obj)
191
- @coder.dump self.class.as_indifferent_hash(obj)
192
- end
270
+ def dump(obj)
271
+ @coder.dump self.class.as_indifferent_hash(obj)
272
+ end
193
273
 
194
- def load(yaml)
195
- self.class.as_indifferent_hash(@coder.load(yaml || ''))
196
- end
274
+ def load(yaml)
275
+ self.class.as_indifferent_hash(@coder.load(yaml || ""))
276
+ end
197
277
 
198
- def self.as_indifferent_hash(obj)
199
- case obj
200
- when ActiveSupport::HashWithIndifferentAccess
201
- obj
202
- when Hash
203
- obj.with_indifferent_access
204
- else
205
- ActiveSupport::HashWithIndifferentAccess.new
278
+ def self.as_indifferent_hash(obj)
279
+ case obj
280
+ when ActiveSupport::HashWithIndifferentAccess
281
+ obj
282
+ when Hash
283
+ obj.with_indifferent_access
284
+ else
285
+ ActiveSupport::HashWithIndifferentAccess.new
286
+ end
206
287
  end
207
288
  end
208
- end
209
289
  end
210
290
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # ActiveRecord::Suppressor prevents the receiver from being saved during
3
5
  # a given block.
@@ -30,10 +32,11 @@ module ActiveRecord
30
32
 
31
33
  module ClassMethods
32
34
  def suppress(&block)
35
+ previous_state = SuppressorRegistry.suppressed[name]
33
36
  SuppressorRegistry.suppressed[name] = true
34
37
  yield
35
38
  ensure
36
- SuppressorRegistry.suppressed[name] = false
39
+ SuppressorRegistry.suppressed[name] = previous_state
37
40
  end
38
41
  end
39
42
 
@@ -1,21 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  class TableMetadata # :nodoc:
3
- delegate :foreign_type, :foreign_key, to: :association, prefix: true
4
- delegate :association_primary_key, to: :association
5
+ delegate :foreign_type, :foreign_key, :join_primary_key, :join_foreign_key, to: :association, prefix: true
5
6
 
6
- def initialize(klass, arel_table, association = nil)
7
+ def initialize(klass, arel_table, association = nil, types = klass)
7
8
  @klass = klass
9
+ @types = types
8
10
  @arel_table = arel_table
9
11
  @association = association
10
12
  end
11
13
 
12
14
  def resolve_column_aliases(hash)
13
- # This method is a hot spot, so for now, use Hash[] to dup the hash.
14
- # https://bugs.ruby-lang.org/issues/7166
15
- new_hash = Hash[hash]
16
- hash.each do |key, _|
17
- if (key.is_a?(Symbol)) && klass.attribute_alias?(key)
18
- new_hash[klass.attribute_alias(key)] = new_hash.delete(key)
15
+ new_hash = hash.dup
16
+ hash.each_key do |key|
17
+ if key.is_a?(Symbol) && new_key = klass.attribute_aliases[key.to_s]
18
+ new_hash[new_key] = new_hash.delete(key)
19
19
  end
20
20
  end
21
21
  new_hash
@@ -30,11 +30,11 @@ module ActiveRecord
30
30
  end
31
31
 
32
32
  def type(column_name)
33
- if klass
34
- klass.type_for_attribute(column_name.to_s)
35
- else
36
- Type::Value.new
37
- end
33
+ types.type_for_attribute(column_name)
34
+ end
35
+
36
+ def has_column?(column_name)
37
+ klass && klass.columns_hash.key?(column_name.to_s)
38
38
  end
39
39
 
40
40
  def associated_with?(association_name)
@@ -42,28 +42,34 @@ module ActiveRecord
42
42
  end
43
43
 
44
44
  def associated_table(table_name)
45
- association = klass._reflect_on_association(table_name) || klass._reflect_on_association(table_name.singularize)
45
+ association = klass._reflect_on_association(table_name) || klass._reflect_on_association(table_name.to_s.singularize)
46
46
 
47
47
  if !association && table_name == arel_table.name
48
48
  return self
49
49
  elsif association && !association.polymorphic?
50
50
  association_klass = association.klass
51
51
  arel_table = association_klass.arel_table.alias(table_name)
52
+ TableMetadata.new(association_klass, arel_table, association)
52
53
  else
53
54
  type_caster = TypeCaster::Connection.new(klass, table_name)
54
- association_klass = nil
55
55
  arel_table = Arel::Table.new(table_name, type_caster: type_caster)
56
+ TableMetadata.new(nil, arel_table, association, type_caster)
56
57
  end
57
-
58
- TableMetadata.new(association_klass, arel_table, association)
59
58
  end
60
59
 
61
60
  def polymorphic_association?
62
61
  association && association.polymorphic?
63
62
  end
64
63
 
65
- protected
64
+ def aggregated_with?(aggregation_name)
65
+ klass && reflect_on_aggregation(aggregation_name)
66
+ end
67
+
68
+ def reflect_on_aggregation(aggregation_name)
69
+ klass.reflect_on_aggregation(aggregation_name)
70
+ end
66
71
 
67
- attr_reader :klass, :arel_table, :association
72
+ private
73
+ attr_reader :klass, :types, :arel_table, :association
68
74
  end
69
75
  end