activerecord 4.2.0 → 6.0.0

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 (372) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +612 -971
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +13 -12
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +267 -248
  8. data/lib/active_record/association_relation.rb +24 -6
  9. data/lib/active_record/associations/alias_tracker.rb +29 -35
  10. data/lib/active_record/associations/association.rb +135 -56
  11. data/lib/active_record/associations/association_scope.rb +103 -131
  12. data/lib/active_record/associations/belongs_to_association.rb +67 -54
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +27 -40
  15. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  16. data/lib/active_record/associations/builder/collection_association.rb +10 -29
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +60 -70
  18. data/lib/active_record/associations/builder/has_many.rb +8 -4
  19. data/lib/active_record/associations/builder/has_one.rb +46 -5
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +138 -274
  22. data/lib/active_record/associations/collection_proxy.rb +252 -151
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +35 -83
  25. data/lib/active_record/associations/has_many_through_association.rb +62 -80
  26. data/lib/active_record/associations/has_one_association.rb +62 -49
  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 -80
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +138 -162
  32. data/lib/active_record/associations/preloader/association.rb +90 -119
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +92 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +48 -23
  37. data/lib/active_record/associations.rb +1737 -1596
  38. data/lib/active_record/attribute_assignment.rb +56 -183
  39. data/lib/active_record/attribute_decorators.rb +39 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +15 -5
  41. data/lib/active_record/attribute_methods/dirty.rb +174 -134
  42. data/lib/active_record/attribute_methods/primary_key.rb +91 -83
  43. data/lib/active_record/attribute_methods/query.rb +6 -5
  44. data/lib/active_record/attribute_methods/read.rb +20 -76
  45. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
  47. data/lib/active_record/attribute_methods/write.rb +33 -55
  48. data/lib/active_record/attribute_methods.rb +124 -143
  49. data/lib/active_record/attributes.rb +214 -74
  50. data/lib/active_record/autosave_association.rb +115 -46
  51. data/lib/active_record/base.rb +60 -49
  52. data/lib/active_record/callbacks.rb +100 -74
  53. data/lib/active_record/coders/json.rb +3 -1
  54. data/lib/active_record/coders/yaml_column.rb +24 -12
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -290
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +247 -108
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +366 -227
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +706 -222
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -87
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +468 -194
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +535 -597
  68. data/lib/active_record/connection_adapters/column.rb +56 -43
  69. data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  71. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -195
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +65 -115
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  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 +5 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  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 -9
  98. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  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 +67 -51
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +474 -286
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -363
  116. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  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 +288 -359
  126. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  127. data/lib/active_record/connection_handling.rb +176 -41
  128. data/lib/active_record/core.rb +266 -233
  129. data/lib/active_record/counter_cache.rb +68 -50
  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 -105
  136. data/lib/active_record/enum.rb +164 -88
  137. data/lib/active_record/errors.rb +189 -53
  138. data/lib/active_record/explain.rb +23 -11
  139. data/lib/active_record/explain_registry.rb +4 -2
  140. data/lib/active_record/explain_subscriber.rb +11 -6
  141. data/lib/active_record/fixture_set/file.rb +35 -9
  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 +226 -495
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +158 -112
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +123 -29
  151. data/lib/active_record/internal_metadata.rb +53 -0
  152. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  153. data/lib/active_record/locale/en.yml +3 -2
  154. data/lib/active_record/locking/optimistic.rb +91 -98
  155. data/lib/active_record/locking/pessimistic.rb +18 -6
  156. data/lib/active_record/log_subscriber.rb +76 -33
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  159. data/lib/active_record/middleware/database_selector.rb +75 -0
  160. data/lib/active_record/migration/command_recorder.rb +177 -90
  161. data/lib/active_record/migration/compatibility.rb +244 -0
  162. data/lib/active_record/migration/join_table.rb +8 -6
  163. data/lib/active_record/migration.rb +634 -288
  164. data/lib/active_record/model_schema.rb +314 -112
  165. data/lib/active_record/nested_attributes.rb +266 -214
  166. data/lib/active_record/no_touching.rb +15 -2
  167. data/lib/active_record/null_relation.rb +24 -37
  168. data/lib/active_record/persistence.rb +559 -124
  169. data/lib/active_record/query_cache.rb +19 -23
  170. data/lib/active_record/querying.rb +43 -29
  171. data/lib/active_record/railtie.rb +148 -47
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +2 -0
  174. data/lib/active_record/railties/controller_runtime.rb +34 -33
  175. data/lib/active_record/railties/databases.rake +338 -202
  176. data/lib/active_record/readonly_attributes.rb +5 -4
  177. data/lib/active_record/reflection.rb +460 -299
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  179. data/lib/active_record/relation/batches.rb +207 -55
  180. data/lib/active_record/relation/calculations.rb +269 -248
  181. data/lib/active_record/relation/delegation.rb +70 -80
  182. data/lib/active_record/relation/finder_methods.rb +279 -255
  183. data/lib/active_record/relation/from_clause.rb +26 -0
  184. data/lib/active_record/relation/merger.rb +83 -69
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
  186. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  187. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  189. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  190. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  192. data/lib/active_record/relation/predicate_builder.rb +116 -92
  193. data/lib/active_record/relation/query_attribute.rb +50 -0
  194. data/lib/active_record/relation/query_methods.rb +574 -391
  195. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  196. data/lib/active_record/relation/spawn_methods.rb +18 -16
  197. data/lib/active_record/relation/where_clause.rb +190 -0
  198. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  199. data/lib/active_record/relation.rb +518 -340
  200. data/lib/active_record/result.rb +79 -42
  201. data/lib/active_record/runtime_registry.rb +6 -4
  202. data/lib/active_record/sanitization.rb +144 -121
  203. data/lib/active_record/schema.rb +21 -24
  204. data/lib/active_record/schema_dumper.rb +112 -93
  205. data/lib/active_record/schema_migration.rb +24 -20
  206. data/lib/active_record/scoping/default.rb +101 -84
  207. data/lib/active_record/scoping/named.rb +86 -33
  208. data/lib/active_record/scoping.rb +45 -26
  209. data/lib/active_record/secure_token.rb +40 -0
  210. data/lib/active_record/serialization.rb +5 -5
  211. data/lib/active_record/statement_cache.rb +73 -36
  212. data/lib/active_record/store.rb +127 -42
  213. data/lib/active_record/suppressor.rb +61 -0
  214. data/lib/active_record/table_metadata.rb +75 -0
  215. data/lib/active_record/tasks/database_tasks.rb +309 -99
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +58 -88
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +82 -31
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +224 -0
  221. data/lib/active_record/timestamp.rb +86 -40
  222. data/lib/active_record/touch_later.rb +66 -0
  223. data/lib/active_record/transactions.rb +215 -139
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  226. data/lib/active_record/type/date.rb +4 -41
  227. data/lib/active_record/type/date_time.rb +4 -38
  228. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  229. data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
  230. data/lib/active_record/type/internal/timezone.rb +17 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +30 -15
  233. data/lib/active_record/type/text.rb +2 -2
  234. data/lib/active_record/type/time.rb +11 -16
  235. data/lib/active_record/type/type_map.rb +15 -17
  236. data/lib/active_record/type/unsigned_integer.rb +9 -7
  237. data/lib/active_record/type.rb +78 -23
  238. data/lib/active_record/type_caster/connection.rb +34 -0
  239. data/lib/active_record/type_caster/map.rb +20 -0
  240. data/lib/active_record/type_caster.rb +9 -0
  241. data/lib/active_record/validations/absence.rb +25 -0
  242. data/lib/active_record/validations/associated.rb +13 -4
  243. data/lib/active_record/validations/length.rb +26 -0
  244. data/lib/active_record/validations/presence.rb +14 -13
  245. data/lib/active_record/validations/uniqueness.rb +43 -46
  246. data/lib/active_record/validations.rb +39 -35
  247. data/lib/active_record/version.rb +3 -1
  248. data/lib/active_record.rb +43 -21
  249. data/lib/arel/alias_predication.rb +9 -0
  250. data/lib/arel/attributes/attribute.rb +37 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/collectors/bind.rb +24 -0
  253. data/lib/arel/collectors/composite.rb +31 -0
  254. data/lib/arel/collectors/plain_string.rb +20 -0
  255. data/lib/arel/collectors/sql_string.rb +20 -0
  256. data/lib/arel/collectors/substitute_binds.rb +28 -0
  257. data/lib/arel/crud.rb +42 -0
  258. data/lib/arel/delete_manager.rb +18 -0
  259. data/lib/arel/errors.rb +9 -0
  260. data/lib/arel/expressions.rb +29 -0
  261. data/lib/arel/factory_methods.rb +49 -0
  262. data/lib/arel/insert_manager.rb +49 -0
  263. data/lib/arel/math.rb +45 -0
  264. data/lib/arel/nodes/and.rb +32 -0
  265. data/lib/arel/nodes/ascending.rb +23 -0
  266. data/lib/arel/nodes/binary.rb +52 -0
  267. data/lib/arel/nodes/bind_param.rb +36 -0
  268. data/lib/arel/nodes/case.rb +55 -0
  269. data/lib/arel/nodes/casted.rb +50 -0
  270. data/lib/arel/nodes/comment.rb +29 -0
  271. data/lib/arel/nodes/count.rb +12 -0
  272. data/lib/arel/nodes/delete_statement.rb +45 -0
  273. data/lib/arel/nodes/descending.rb +23 -0
  274. data/lib/arel/nodes/equality.rb +18 -0
  275. data/lib/arel/nodes/extract.rb +24 -0
  276. data/lib/arel/nodes/false.rb +16 -0
  277. data/lib/arel/nodes/full_outer_join.rb +8 -0
  278. data/lib/arel/nodes/function.rb +44 -0
  279. data/lib/arel/nodes/grouping.rb +8 -0
  280. data/lib/arel/nodes/in.rb +8 -0
  281. data/lib/arel/nodes/infix_operation.rb +80 -0
  282. data/lib/arel/nodes/inner_join.rb +8 -0
  283. data/lib/arel/nodes/insert_statement.rb +37 -0
  284. data/lib/arel/nodes/join_source.rb +20 -0
  285. data/lib/arel/nodes/matches.rb +18 -0
  286. data/lib/arel/nodes/named_function.rb +23 -0
  287. data/lib/arel/nodes/node.rb +50 -0
  288. data/lib/arel/nodes/node_expression.rb +13 -0
  289. data/lib/arel/nodes/outer_join.rb +8 -0
  290. data/lib/arel/nodes/over.rb +15 -0
  291. data/lib/arel/nodes/regexp.rb +16 -0
  292. data/lib/arel/nodes/right_outer_join.rb +8 -0
  293. data/lib/arel/nodes/select_core.rb +67 -0
  294. data/lib/arel/nodes/select_statement.rb +41 -0
  295. data/lib/arel/nodes/sql_literal.rb +16 -0
  296. data/lib/arel/nodes/string_join.rb +11 -0
  297. data/lib/arel/nodes/table_alias.rb +27 -0
  298. data/lib/arel/nodes/terminal.rb +16 -0
  299. data/lib/arel/nodes/true.rb +16 -0
  300. data/lib/arel/nodes/unary.rb +45 -0
  301. data/lib/arel/nodes/unary_operation.rb +20 -0
  302. data/lib/arel/nodes/unqualified_column.rb +22 -0
  303. data/lib/arel/nodes/update_statement.rb +41 -0
  304. data/lib/arel/nodes/values_list.rb +9 -0
  305. data/lib/arel/nodes/window.rb +126 -0
  306. data/lib/arel/nodes/with.rb +11 -0
  307. data/lib/arel/nodes.rb +68 -0
  308. data/lib/arel/order_predications.rb +13 -0
  309. data/lib/arel/predications.rb +257 -0
  310. data/lib/arel/select_manager.rb +271 -0
  311. data/lib/arel/table.rb +110 -0
  312. data/lib/arel/tree_manager.rb +72 -0
  313. data/lib/arel/update_manager.rb +34 -0
  314. data/lib/arel/visitors/depth_first.rb +204 -0
  315. data/lib/arel/visitors/dot.rb +297 -0
  316. data/lib/arel/visitors/ibm_db.rb +34 -0
  317. data/lib/arel/visitors/informix.rb +62 -0
  318. data/lib/arel/visitors/mssql.rb +157 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +159 -0
  321. data/lib/arel/visitors/oracle12.rb +66 -0
  322. data/lib/arel/visitors/postgresql.rb +110 -0
  323. data/lib/arel/visitors/sqlite.rb +39 -0
  324. data/lib/arel/visitors/to_sql.rb +889 -0
  325. data/lib/arel/visitors/visitor.rb +46 -0
  326. data/lib/arel/visitors/where_sql.rb +23 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +51 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  331. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  333. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  334. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -8
  335. data/lib/rails/generators/active_record/migration.rb +31 -1
  336. data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +166 -60
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  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 -23
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  347. data/lib/active_record/attribute.rb +0 -149
  348. data/lib/active_record/attribute_set/builder.rb +0 -86
  349. data/lib/active_record/attribute_set.rb +0 -77
  350. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  351. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  352. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  353. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  354. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  355. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  356. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  357. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  358. data/lib/active_record/type/big_integer.rb +0 -13
  359. data/lib/active_record/type/binary.rb +0 -50
  360. data/lib/active_record/type/boolean.rb +0 -30
  361. data/lib/active_record/type/decimal.rb +0 -40
  362. data/lib/active_record/type/decorator.rb +0 -14
  363. data/lib/active_record/type/float.rb +0 -19
  364. data/lib/active_record/type/integer.rb +0 -55
  365. data/lib/active_record/type/mutable.rb +0 -16
  366. data/lib/active_record/type/numeric.rb +0 -36
  367. data/lib/active_record/type/string.rb +0 -36
  368. data/lib/active_record/type/time_value.rb +0 -38
  369. data/lib/active_record/type/value.rb +0 -101
  370. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  371. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  372. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,49 +1,41 @@
1
- require 'active_support/core_ext/string/conversions'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/conversions"
2
4
 
3
5
  module ActiveRecord
4
6
  module Associations
5
- # Keeps track of table aliases for ActiveRecord::Associations::ClassMethods::JoinDependency and
6
- # ActiveRecord::Associations::ThroughAssociationScope
7
+ # Keeps track of table aliases for ActiveRecord::Associations::JoinDependency
7
8
  class AliasTracker # :nodoc:
8
- attr_reader :aliases, :connection
9
-
10
- def self.empty(connection)
11
- new connection, Hash.new(0)
12
- end
13
-
14
- def self.create(connection, table_joins)
15
- if table_joins.empty?
16
- empty connection
9
+ def self.create(connection, initial_table, joins)
10
+ if joins.empty?
11
+ aliases = Hash.new(0)
17
12
  else
18
- aliases = Hash.new { |h,k|
19
- h[k] = initial_count_for(connection, k, table_joins)
13
+ aliases = Hash.new { |h, k|
14
+ h[k] = initial_count_for(connection, k, joins)
20
15
  }
21
- new connection, aliases
22
16
  end
17
+ aliases[initial_table] = 1
18
+ new(connection, aliases)
23
19
  end
24
20
 
25
21
  def self.initial_count_for(connection, name, table_joins)
26
- # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase
27
- quoted_name = connection.quote_table_name(name).downcase
22
+ quoted_name = nil
28
23
 
29
24
  counts = table_joins.map do |join|
30
25
  if join.is_a?(Arel::Nodes::StringJoin)
26
+ # quoted_name should be case ignored as some database adapters (Oracle) return quoted name in uppercase
27
+ quoted_name ||= connection.quote_table_name(name)
28
+
31
29
  # Table names + table aliases
32
- join.left.downcase.scan(
33
- /join(?:\s+\w+)?\s+(\S+\s+)?#{quoted_name}\son/
30
+ join.left.scan(
31
+ /JOIN(?:\s+\w+)?\s+(?:\S+\s+)?(?:#{quoted_name}|#{name})\sON/i
34
32
  ).size
35
- elsif join.respond_to? :left
36
- join.left.table_name == name ? 1 : 0
33
+ elsif join.is_a?(Arel::Nodes::Join)
34
+ join.left.name == name ? 1 : 0
35
+ elsif join.is_a?(Hash)
36
+ join[name]
37
37
  else
38
- # this branch is reached by two tests:
39
- #
40
- # activerecord/test/cases/associations/cascaded_eager_loading_test.rb:37
41
- # with :posts
42
- #
43
- # activerecord/test/cases/associations/eager_test.rb:1133
44
- # with :comments
45
- #
46
- 0
38
+ raise ArgumentError, "joins list should be initialized by list of Arel::Nodes::Join"
47
39
  end
48
40
  end
49
41
 
@@ -56,14 +48,14 @@ module ActiveRecord
56
48
  @connection = connection
57
49
  end
58
50
 
59
- def aliased_table_for(table_name, aliased_name)
51
+ def aliased_table_for(table_name, aliased_name, type_caster)
60
52
  if aliases[table_name].zero?
61
53
  # If it's zero, we can have our table_name
62
54
  aliases[table_name] = 1
63
- Arel::Table.new(table_name)
55
+ Arel::Table.new(table_name, type_caster: type_caster)
64
56
  else
65
57
  # Otherwise, we need to use an alias
66
- aliased_name = connection.table_alias_for(aliased_name)
58
+ aliased_name = @connection.table_alias_for(aliased_name)
67
59
 
68
60
  # Update the count
69
61
  aliases[aliased_name] += 1
@@ -73,14 +65,16 @@ module ActiveRecord
73
65
  else
74
66
  aliased_name
75
67
  end
76
- Arel::Table.new(table_name).alias(table_alias)
68
+ Arel::Table.new(table_name, type_caster: type_caster).alias(table_alias)
77
69
  end
78
70
  end
79
71
 
72
+ attr_reader :aliases
73
+
80
74
  private
81
75
 
82
76
  def truncate(name)
83
- name.slice(0, connection.table_alias_length - 2)
77
+ name.slice(0, @connection.table_alias_length - 2)
84
78
  end
85
79
  end
86
80
  end
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/array/wrap'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/wrap"
2
4
 
3
5
  module ActiveRecord
4
6
  module Associations
@@ -8,18 +10,34 @@ module ActiveRecord
8
10
  #
9
11
  # Association
10
12
  # SingularAssociation
11
- # HasOneAssociation
13
+ # HasOneAssociation + ForeignAssociation
12
14
  # HasOneThroughAssociation + ThroughAssociation
13
15
  # BelongsToAssociation
14
16
  # BelongsToPolymorphicAssociation
15
17
  # CollectionAssociation
16
- # HasManyAssociation
18
+ # HasManyAssociation + ForeignAssociation
17
19
  # HasManyThroughAssociation + ThroughAssociation
20
+ #
21
+ # Associations in Active Record are middlemen between the object that
22
+ # holds the association, known as the <tt>owner</tt>, and the associated
23
+ # result set, known as the <tt>target</tt>. Association metadata is available in
24
+ # <tt>reflection</tt>, which is an instance of <tt>ActiveRecord::Reflection::AssociationReflection</tt>.
25
+ #
26
+ # For example, given
27
+ #
28
+ # class Blog < ActiveRecord::Base
29
+ # has_many :posts
30
+ # end
31
+ #
32
+ # blog = Blog.first
33
+ #
34
+ # The association of <tt>blog.posts</tt> has the object +blog+ as its
35
+ # <tt>owner</tt>, the collection of its posts as <tt>target</tt>, and
36
+ # the <tt>reflection</tt> object represents a <tt>:has_many</tt> macro.
18
37
  class Association #:nodoc:
19
38
  attr_reader :owner, :target, :reflection
20
- attr_accessor :inversed
21
39
 
22
- delegate :options, :to => :reflection
40
+ delegate :options, to: :reflection
23
41
 
24
42
  def initialize(owner, reflection)
25
43
  reflection.check_validity!
@@ -30,14 +48,6 @@ module ActiveRecord
30
48
  reset_scope
31
49
  end
32
50
 
33
- # Returns the name of the table of the associated class:
34
- #
35
- # post.comments.aliased_table_name # => "comments"
36
- #
37
- def aliased_table_name
38
- klass.table_name
39
- end
40
-
41
51
  # Resets the \loaded flag to +false+ and sets the \target to +nil+.
42
52
  def reset
43
53
  @loaded = false
@@ -47,7 +57,9 @@ module ActiveRecord
47
57
  end
48
58
 
49
59
  # Reloads the \target and returns +self+ on success.
50
- def reload
60
+ # The QueryCache is cleared if +force+ is true.
61
+ def reload(force = false)
62
+ klass.connection.clear_query_cache if force && klass
51
63
  reset
52
64
  reset_scope
53
65
  load_target
@@ -73,7 +85,7 @@ module ActiveRecord
73
85
  #
74
86
  # Note that if the target has not been loaded, it is not considered stale.
75
87
  def stale_target?
76
- !inversed && loaded? && @stale_state != stale_state
88
+ !@inversed && loaded? && @stale_state != stale_state
77
89
  end
78
90
 
79
91
  # Sets the target of this association to <tt>\target</tt>, and the \loaded flag to +true+.
@@ -83,19 +95,7 @@ module ActiveRecord
83
95
  end
84
96
 
85
97
  def scope
86
- target_scope.merge(association_scope)
87
- end
88
-
89
- # The scope for this association.
90
- #
91
- # Note that the association_scope is merged into the target_scope only when the
92
- # scope method is called. This is because at that point the call may be surrounded
93
- # by scope.scoping { ... } or with_scope { ... } etc, which affects the scope which
94
- # actually gets built.
95
- def association_scope
96
- if klass
97
- @association_scope ||= AssociationScope.scope(self, klass.connection)
98
- end
98
+ target_scope.merge!(association_scope)
99
99
  end
100
100
 
101
101
  def reset_scope
@@ -104,24 +104,46 @@ module ActiveRecord
104
104
 
105
105
  # Set the inverse association, if possible
106
106
  def set_inverse_instance(record)
107
- if invertible_for?(record)
108
- inverse = record.association(inverse_reflection_for(record).name)
109
- inverse.target = owner
110
- inverse.inversed = true
107
+ if inverse = inverse_association_for(record)
108
+ inverse.inversed_from(owner)
109
+ end
110
+ record
111
+ end
112
+
113
+ def set_inverse_instance_from_queries(record)
114
+ if inverse = inverse_association_for(record)
115
+ inverse.inversed_from_queries(owner)
111
116
  end
112
117
  record
113
118
  end
114
119
 
120
+ # Remove the inverse association, if possible
121
+ def remove_inverse_instance(record)
122
+ if inverse = inverse_association_for(record)
123
+ inverse.inversed_from(nil)
124
+ end
125
+ end
126
+
127
+ def inversed_from(record)
128
+ self.target = record
129
+ @inversed = !!record
130
+ end
131
+ alias :inversed_from_queries :inversed_from
132
+
115
133
  # Returns the class of the target. belongs_to polymorphic overrides this to look at the
116
134
  # polymorphic_type field on the owner.
117
135
  def klass
118
136
  reflection.klass
119
137
  end
120
138
 
121
- # Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
122
- # through association's scope)
123
- def target_scope
124
- AssociationRelation.create(klass, klass.arel_table, self).merge!(klass.all)
139
+ def extensions
140
+ extensions = klass.default_extensions | reflection.extensions
141
+
142
+ if reflection.scope
143
+ extensions |= reflection.scope_for(klass.unscoped, owner).extensions
144
+ end
145
+
146
+ extensions
125
147
  end
126
148
 
127
149
  # Loads the \target if needed and returns it.
@@ -143,17 +165,9 @@ module ActiveRecord
143
165
  reset
144
166
  end
145
167
 
146
- def interpolate(sql, record = nil)
147
- if sql.respond_to?(:to_proc)
148
- owner.instance_exec(record, &sql)
149
- else
150
- sql
151
- end
152
- end
153
-
154
- # We can't dump @reflection since it contains the scope proc
168
+ # We can't dump @reflection and @through_reflection since it contains the scope proc
155
169
  def marshal_dump
156
- ivars = (instance_variables - [:@reflection]).map { |name| [name, instance_variable_get(name)] }
170
+ ivars = (instance_variables - [:@reflection, :@through_reflection]).map { |name| [name, instance_variable_get(name)] }
157
171
  [@reflection.name, ivars]
158
172
  end
159
173
 
@@ -163,14 +177,60 @@ module ActiveRecord
163
177
  @reflection = @owner.class._reflect_on_association(reflection_name)
164
178
  end
165
179
 
166
- def initialize_attributes(record) #:nodoc:
180
+ def initialize_attributes(record, except_from_scope_attributes = nil) #:nodoc:
181
+ except_from_scope_attributes ||= {}
167
182
  skip_assign = [reflection.foreign_key, reflection.type].compact
168
- attributes = create_scope.except(*(record.changed - skip_assign))
169
- record.assign_attributes(attributes)
183
+ assigned_keys = record.changed_attribute_names_to_save
184
+ assigned_keys += except_from_scope_attributes.keys.map(&:to_s)
185
+ attributes = scope_for_create.except!(*(assigned_keys - skip_assign))
186
+ record.send(:_assign_attributes, attributes) if attributes.any?
170
187
  set_inverse_instance(record)
171
188
  end
172
189
 
190
+ def create(attributes = {}, &block)
191
+ _create_record(attributes, &block)
192
+ end
193
+
194
+ def create!(attributes = {}, &block)
195
+ _create_record(attributes, true, &block)
196
+ end
197
+
173
198
  private
199
+ def find_target
200
+ scope = self.scope
201
+ return scope.to_a if skip_statement_cache?(scope)
202
+
203
+ conn = klass.connection
204
+ sc = reflection.association_scope_cache(conn, owner) do |params|
205
+ as = AssociationScope.create { params.bind }
206
+ target_scope.merge!(as.scope(self))
207
+ end
208
+
209
+ binds = AssociationScope.get_bind_values(owner, reflection.chain)
210
+ sc.execute(binds, conn) { |record| set_inverse_instance(record) } || []
211
+ end
212
+
213
+ # The scope for this association.
214
+ #
215
+ # Note that the association_scope is merged into the target_scope only when the
216
+ # scope method is called. This is because at that point the call may be surrounded
217
+ # by scope.scoping { ... } or unscoped { ... } etc, which affects the scope which
218
+ # actually gets built.
219
+ def association_scope
220
+ if klass
221
+ @association_scope ||= AssociationScope.scope(self)
222
+ end
223
+ end
224
+
225
+ # Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
226
+ # through association's scope)
227
+ def target_scope
228
+ AssociationRelation.create(klass, self).merge!(klass.scope_for_association)
229
+ end
230
+
231
+ def scope_for_create
232
+ scope.scope_for_create
233
+ end
174
234
 
175
235
  def find_target?
176
236
  !loaded? && (!owner.new_record? || foreign_key_present?) && klass
@@ -182,8 +242,8 @@ module ActiveRecord
182
242
  if (reflection.has_one? || reflection.collection?) && !options[:through]
183
243
  attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
184
244
 
185
- if reflection.options[:as]
186
- attributes[reflection.type] = owner.class.base_class.name
245
+ if reflection.type
246
+ attributes[reflection.type] = owner.class.polymorphic_name
187
247
  end
188
248
  end
189
249
 
@@ -211,9 +271,19 @@ module ActiveRecord
211
271
  # the kind of the class of the associated objects. Meant to be used as
212
272
  # a sanity check when you are about to assign an associated record.
213
273
  def raise_on_type_mismatch!(record)
214
- unless record.is_a?(reflection.klass) || record.is_a?(reflection.class_name.constantize)
215
- message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})"
216
- raise ActiveRecord::AssociationTypeMismatch, message
274
+ unless record.is_a?(reflection.klass)
275
+ fresh_class = reflection.class_name.safe_constantize
276
+ unless fresh_class && record.is_a?(fresh_class)
277
+ message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, "\
278
+ "got #{record.inspect} which is an instance of #{record.class}(##{record.class.object_id})"
279
+ raise ActiveRecord::AssociationTypeMismatch, message
280
+ end
281
+ end
282
+ end
283
+
284
+ def inverse_association_for(record)
285
+ if invertible_for?(record)
286
+ record.association(inverse_reflection_for(record).name)
217
287
  end
218
288
  end
219
289
 
@@ -239,15 +309,24 @@ module ActiveRecord
239
309
  # so that when stale_state is different from the value stored on the last find_target,
240
310
  # the target is stale.
241
311
  #
242
- # This is only relevant to certain associations, which is why it returns nil by default.
312
+ # This is only relevant to certain associations, which is why it returns +nil+ by default.
243
313
  def stale_state
244
314
  end
245
315
 
246
316
  def build_record(attributes)
247
317
  reflection.build_association(attributes) do |record|
248
- initialize_attributes(record)
318
+ initialize_attributes(record, attributes)
319
+ yield(record) if block_given?
249
320
  end
250
321
  end
322
+
323
+ # Returns true if statement cache should be skipped on the association reader.
324
+ def skip_statement_cache?(scope)
325
+ reflection.has_scope? ||
326
+ scope.eager_loading? ||
327
+ klass.scope_attributes? ||
328
+ reflection.source_reflection.active_record.default_scopes.any?
329
+ end
251
330
  end
252
331
  end
253
332
  end