activerecord 3.2.6 → 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 (371) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +611 -6417
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +44 -47
  5. data/examples/performance.rb +79 -71
  6. data/examples/simple.rb +6 -5
  7. data/lib/active_record/aggregations.rb +268 -238
  8. data/lib/active_record/association_relation.rb +40 -0
  9. data/lib/active_record/associations/alias_tracker.rb +47 -42
  10. data/lib/active_record/associations/association.rb +173 -81
  11. data/lib/active_record/associations/association_scope.rb +124 -92
  12. data/lib/active_record/associations/belongs_to_association.rb +83 -38
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +11 -9
  14. data/lib/active_record/associations/builder/association.rb +113 -32
  15. data/lib/active_record/associations/builder/belongs_to.rb +105 -60
  16. data/lib/active_record/associations/builder/collection_association.rb +53 -56
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +98 -41
  18. data/lib/active_record/associations/builder/has_many.rb +11 -63
  19. data/lib/active_record/associations/builder/has_one.rb +47 -45
  20. data/lib/active_record/associations/builder/singular_association.rb +30 -18
  21. data/lib/active_record/associations/collection_association.rb +217 -295
  22. data/lib/active_record/associations/collection_proxy.rb +1074 -77
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +78 -50
  25. data/lib/active_record/associations/has_many_through_association.rb +99 -61
  26. data/lib/active_record/associations/has_one_association.rb +75 -30
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +45 -119
  29. data/lib/active_record/associations/join_dependency/join_base.rb +11 -12
  30. data/lib/active_record/associations/join_dependency/join_part.rb +35 -42
  31. data/lib/active_record/associations/join_dependency.rb +208 -164
  32. data/lib/active_record/associations/preloader/association.rb +93 -87
  33. data/lib/active_record/associations/preloader/through_association.rb +87 -38
  34. data/lib/active_record/associations/preloader.rb +134 -110
  35. data/lib/active_record/associations/singular_association.rb +19 -24
  36. data/lib/active_record/associations/through_association.rb +61 -27
  37. data/lib/active_record/associations.rb +1766 -1505
  38. data/lib/active_record/attribute_assignment.rb +57 -193
  39. data/lib/active_record/attribute_decorators.rb +90 -0
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +58 -8
  41. data/lib/active_record/attribute_methods/dirty.rb +187 -67
  42. data/lib/active_record/attribute_methods/primary_key.rb +100 -78
  43. data/lib/active_record/attribute_methods/query.rb +10 -8
  44. data/lib/active_record/attribute_methods/read.rb +29 -118
  45. data/lib/active_record/attribute_methods/serialization.rb +60 -72
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +69 -42
  47. data/lib/active_record/attribute_methods/write.rb +36 -44
  48. data/lib/active_record/attribute_methods.rb +306 -161
  49. data/lib/active_record/attributes.rb +279 -0
  50. data/lib/active_record/autosave_association.rb +324 -238
  51. data/lib/active_record/base.rb +114 -507
  52. data/lib/active_record/callbacks.rb +147 -83
  53. data/lib/active_record/coders/json.rb +15 -0
  54. data/lib/active_record/coders/yaml_column.rb +32 -23
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +962 -279
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +32 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +331 -209
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +95 -23
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +201 -65
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +23 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +510 -289
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +93 -0
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1182 -313
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +323 -0
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +585 -120
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +610 -463
  68. data/lib/active_record/connection_adapters/column.rb +58 -233
  69. data/lib/active_record/connection_adapters/connection_specification.rb +297 -0
  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 +75 -207
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -0
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +182 -0
  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 +92 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +53 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +50 -0
  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 +23 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +21 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +71 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
  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 +41 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +65 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +97 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +113 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +26 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +34 -0
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +205 -0
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +43 -0
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +222 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +776 -0
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +81 -0
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +695 -1052
  116. data/lib/active_record/connection_adapters/schema_cache.rb +115 -24
  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 +528 -26
  126. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  127. data/lib/active_record/connection_handling.rb +267 -0
  128. data/lib/active_record/core.rb +599 -0
  129. data/lib/active_record/counter_cache.rb +177 -103
  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 +107 -64
  136. data/lib/active_record/enum.rb +274 -0
  137. data/lib/active_record/errors.rb +254 -61
  138. data/lib/active_record/explain.rb +35 -70
  139. data/lib/active_record/explain_registry.rb +32 -0
  140. data/lib/active_record/explain_subscriber.rb +18 -8
  141. data/lib/active_record/fixture_set/file.rb +82 -0
  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 +291 -475
  147. data/lib/active_record/gem_version.rb +17 -0
  148. data/lib/active_record/inheritance.rb +219 -100
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +175 -17
  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 +9 -1
  154. data/lib/active_record/locking/optimistic.rb +106 -92
  155. data/lib/active_record/locking/pessimistic.rb +23 -11
  156. data/lib/active_record/log_subscriber.rb +80 -30
  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 +235 -56
  161. data/lib/active_record/migration/compatibility.rb +244 -0
  162. data/lib/active_record/migration/join_table.rb +17 -0
  163. data/lib/active_record/migration.rb +917 -301
  164. data/lib/active_record/model_schema.rb +351 -175
  165. data/lib/active_record/nested_attributes.rb +366 -235
  166. data/lib/active_record/no_touching.rb +65 -0
  167. data/lib/active_record/null_relation.rb +68 -0
  168. data/lib/active_record/persistence.rb +761 -166
  169. data/lib/active_record/query_cache.rb +22 -44
  170. data/lib/active_record/querying.rb +55 -31
  171. data/lib/active_record/railtie.rb +185 -47
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +5 -4
  174. data/lib/active_record/railties/controller_runtime.rb +35 -33
  175. data/lib/active_record/railties/databases.rake +366 -463
  176. data/lib/active_record/readonly_attributes.rb +4 -6
  177. data/lib/active_record/reflection.rb +736 -228
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  179. data/lib/active_record/relation/batches.rb +252 -52
  180. data/lib/active_record/relation/calculations.rb +340 -270
  181. data/lib/active_record/relation/delegation.rb +117 -36
  182. data/lib/active_record/relation/finder_methods.rb +439 -286
  183. data/lib/active_record/relation/from_clause.rb +26 -0
  184. data/lib/active_record/relation/merger.rb +184 -0
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +49 -0
  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 +19 -0
  192. data/lib/active_record/relation/predicate_builder.rb +131 -39
  193. data/lib/active_record/relation/query_attribute.rb +50 -0
  194. data/lib/active_record/relation/query_methods.rb +1163 -221
  195. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  196. data/lib/active_record/relation/spawn_methods.rb +49 -120
  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 +671 -349
  200. data/lib/active_record/result.rb +149 -15
  201. data/lib/active_record/runtime_registry.rb +24 -0
  202. data/lib/active_record/sanitization.rb +153 -133
  203. data/lib/active_record/schema.rb +22 -19
  204. data/lib/active_record/schema_dumper.rb +178 -112
  205. data/lib/active_record/schema_migration.rb +60 -0
  206. data/lib/active_record/scoping/default.rb +107 -98
  207. data/lib/active_record/scoping/named.rb +130 -115
  208. data/lib/active_record/scoping.rb +77 -123
  209. data/lib/active_record/secure_token.rb +40 -0
  210. data/lib/active_record/serialization.rb +10 -6
  211. data/lib/active_record/statement_cache.rb +148 -0
  212. data/lib/active_record/store.rb +256 -16
  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 +506 -0
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +115 -0
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +141 -0
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +77 -0
  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 +93 -39
  222. data/lib/active_record/touch_later.rb +66 -0
  223. data/lib/active_record/transactions.rb +260 -129
  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 +9 -0
  227. data/lib/active_record/type/date_time.rb +9 -0
  228. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  229. data/lib/active_record/type/hash_lookup_type_map.rb +25 -0
  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 +71 -0
  233. data/lib/active_record/type/text.rb +11 -0
  234. data/lib/active_record/type/time.rb +21 -0
  235. data/lib/active_record/type/type_map.rb +62 -0
  236. data/lib/active_record/type/unsigned_integer.rb +17 -0
  237. data/lib/active_record/type.rb +78 -0
  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 +35 -18
  243. data/lib/active_record/validations/length.rb +26 -0
  244. data/lib/active_record/validations/presence.rb +68 -0
  245. data/lib/active_record/validations/uniqueness.rb +123 -77
  246. data/lib/active_record/validations.rb +54 -43
  247. data/lib/active_record/version.rb +7 -7
  248. data/lib/active_record.rb +97 -49
  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 +59 -9
  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.tt +48 -0
  335. data/lib/rails/generators/active_record/migration.rb +41 -8
  336. data/lib/rails/generators/active_record/model/model_generator.rb +24 -22
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +1 -1
  339. data/lib/rails/generators/active_record.rb +10 -16
  340. metadata +285 -149
  341. data/examples/associations.png +0 -0
  342. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
  343. data/lib/active_record/associations/join_helper.rb +0 -55
  344. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  345. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  346. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  347. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  348. data/lib/active_record/associations/preloader/has_many_through.rb +0 -15
  349. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  350. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  351. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  352. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  353. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -188
  354. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -426
  355. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -579
  356. data/lib/active_record/dynamic_finder_match.rb +0 -68
  357. data/lib/active_record/dynamic_scope_match.rb +0 -23
  358. data/lib/active_record/fixtures/file.rb +0 -65
  359. data/lib/active_record/identity_map.rb +0 -162
  360. data/lib/active_record/observer.rb +0 -121
  361. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  362. data/lib/active_record/serializers/xml_serializer.rb +0 -203
  363. data/lib/active_record/session_store.rb +0 -358
  364. data/lib/active_record/test_case.rb +0 -73
  365. data/lib/rails/generators/active_record/migration/templates/migration.rb +0 -34
  366. data/lib/rails/generators/active_record/model/templates/migration.rb +0 -15
  367. data/lib/rails/generators/active_record/model/templates/model.rb +0 -12
  368. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  369. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  370. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  371. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,221 +1,85 @@
1
- require 'active_support/concern'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_model/forbidden_attributes_protection"
2
4
 
3
5
  module ActiveRecord
4
6
  module AttributeAssignment
5
- extend ActiveSupport::Concern
6
- include ActiveModel::MassAssignmentSecurity
7
-
8
- module ClassMethods
9
- private
10
-
11
- # The primary key and inheritance column can never be set by mass-assignment for security reasons.
12
- def attributes_protected_by_default
13
- default = [ primary_key, inheritance_column ]
14
- default << 'id' unless primary_key.eql? 'id'
15
- default
16
- end
17
- end
7
+ include ActiveModel::AttributeAssignment
18
8
 
19
- # Allows you to set all the attributes at once by passing in a hash with keys
20
- # matching the attribute names (which again matches the column names).
21
- #
22
- # If any attributes are protected by either +attr_protected+ or
23
- # +attr_accessible+ then only settable attributes will be assigned.
24
- #
25
- # class User < ActiveRecord::Base
26
- # attr_protected :is_admin
27
- # end
28
- #
29
- # user = User.new
30
- # user.attributes = { :username => 'Phusion', :is_admin => true }
31
- # user.username # => "Phusion"
32
- # user.is_admin? # => false
33
- def attributes=(new_attributes)
34
- return unless new_attributes.is_a?(Hash)
35
-
36
- assign_attributes(new_attributes)
37
- end
38
-
39
- # Allows you to set all the attributes for a particular mass-assignment
40
- # security role by passing in a hash of attributes with keys matching
41
- # the attribute names (which again matches the column names) and the role
42
- # name using the :as option.
43
- #
44
- # To bypass mass-assignment security you can use the :without_protection => true
45
- # option.
46
- #
47
- # class User < ActiveRecord::Base
48
- # attr_accessible :name
49
- # attr_accessible :name, :is_admin, :as => :admin
50
- # end
51
- #
52
- # user = User.new
53
- # user.assign_attributes({ :name => 'Josh', :is_admin => true })
54
- # user.name # => "Josh"
55
- # user.is_admin? # => false
56
- #
57
- # user = User.new
58
- # user.assign_attributes({ :name => 'Josh', :is_admin => true }, :as => :admin)
59
- # user.name # => "Josh"
60
- # user.is_admin? # => true
61
- #
62
- # user = User.new
63
- # user.assign_attributes({ :name => 'Josh', :is_admin => true }, :without_protection => true)
64
- # user.name # => "Josh"
65
- # user.is_admin? # => true
66
- def assign_attributes(new_attributes, options = {})
67
- return unless new_attributes
68
-
69
- attributes = new_attributes.stringify_keys
70
- multi_parameter_attributes = []
71
- nested_parameter_attributes = []
72
- @mass_assignment_options = options
9
+ private
73
10
 
74
- unless options[:without_protection]
75
- attributes = sanitize_for_mass_assignment(attributes, mass_assignment_role)
76
- end
11
+ def _assign_attributes(attributes)
12
+ multi_parameter_attributes = {}
13
+ nested_parameter_attributes = {}
77
14
 
78
- attributes.each do |k, v|
79
- if k.include?("(")
80
- multi_parameter_attributes << [ k, v ]
81
- elsif respond_to?("#{k}=")
82
- if v.is_a?(Hash)
83
- nested_parameter_attributes << [ k, v ]
84
- else
85
- send("#{k}=", v)
15
+ attributes.each do |k, v|
16
+ if k.include?("(")
17
+ multi_parameter_attributes[k] = attributes.delete(k)
18
+ elsif v.is_a?(Hash)
19
+ nested_parameter_attributes[k] = attributes.delete(k)
86
20
  end
87
- else
88
- raise(UnknownAttributeError, "unknown attribute: #{k}")
89
21
  end
90
- end
22
+ super(attributes)
91
23
 
92
- # assign any deferred nested attributes after the base attributes have been set
93
- nested_parameter_attributes.each do |k,v|
94
- send("#{k}=", v)
24
+ assign_nested_parameter_attributes(nested_parameter_attributes) unless nested_parameter_attributes.empty?
25
+ assign_multiparameter_attributes(multi_parameter_attributes) unless multi_parameter_attributes.empty?
95
26
  end
96
27
 
97
- @mass_assignment_options = nil
98
- assign_multiparameter_attributes(multi_parameter_attributes)
99
- end
100
-
101
- protected
102
-
103
- def mass_assignment_options
104
- @mass_assignment_options ||= {}
105
- end
106
-
107
- def mass_assignment_role
108
- mass_assignment_options[:as] || :default
109
- end
110
-
111
- private
112
-
113
- # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
114
- # by calling new on the column type or aggregation type (through composed_of) object with these parameters.
115
- # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
116
- # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
117
- # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum,
118
- # f for Float, s for String, and a for Array. If all the values for a given attribute are empty, the
119
- # attribute will be set to nil.
120
- def assign_multiparameter_attributes(pairs)
121
- execute_callstack_for_multiparameter_attributes(
122
- extract_callstack_for_multiparameter_attributes(pairs)
123
- )
124
- end
28
+ # Assign any deferred nested attributes after the base attributes have been set.
29
+ def assign_nested_parameter_attributes(pairs)
30
+ pairs.each { |k, v| _assign_attribute(k, v) }
31
+ end
125
32
 
126
- def instantiate_time_object(name, values)
127
- if self.class.send(:create_time_zone_conversion_attribute?, name, column_for_attribute(name))
128
- Time.zone.local(*values)
129
- else
130
- Time.time_with_datetime_fallback(self.class.default_timezone, *values)
33
+ # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
34
+ # by calling new on the column type or aggregation type (through composed_of) object with these parameters.
35
+ # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
36
+ # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
37
+ # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Integer and
38
+ # f for Float. If all the values for a given attribute are empty, the attribute will be set to +nil+.
39
+ def assign_multiparameter_attributes(pairs)
40
+ execute_callstack_for_multiparameter_attributes(
41
+ extract_callstack_for_multiparameter_attributes(pairs)
42
+ )
131
43
  end
132
- end
133
44
 
134
- def execute_callstack_for_multiparameter_attributes(callstack)
135
- errors = []
136
- callstack.each do |name, values_with_empty_parameters|
137
- begin
138
- send(name + "=", read_value_from_parameter(name, values_with_empty_parameters))
45
+ def execute_callstack_for_multiparameter_attributes(callstack)
46
+ errors = []
47
+ callstack.each do |name, values_with_empty_parameters|
48
+ if values_with_empty_parameters.each_value.all?(&:nil?)
49
+ values = nil
50
+ else
51
+ values = values_with_empty_parameters
52
+ end
53
+ send("#{name}=", values)
139
54
  rescue => ex
140
- errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name}", ex, name)
55
+ errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name} (#{ex.message})", ex, name)
56
+ end
57
+ unless errors.empty?
58
+ error_descriptions = errors.map(&:message).join(",")
59
+ raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]"
141
60
  end
142
61
  end
143
- unless errors.empty?
144
- raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
145
- end
146
- end
147
62
 
148
- def read_value_from_parameter(name, values_hash_from_param)
149
- klass = (self.class.reflect_on_aggregation(name.to_sym) || column_for_attribute(name)).klass
150
- if values_hash_from_param.values.all?{|v|v.nil?}
151
- nil
152
- elsif klass == Time
153
- read_time_parameter_value(name, values_hash_from_param)
154
- elsif klass == Date
155
- read_date_parameter_value(name, values_hash_from_param)
156
- else
157
- read_other_parameter_value(klass, name, values_hash_from_param)
158
- end
159
- end
63
+ def extract_callstack_for_multiparameter_attributes(pairs)
64
+ attributes = {}
160
65
 
161
- def read_time_parameter_value(name, values_hash_from_param)
162
- # If Date bits were not provided, error
163
- raise "Missing Parameter" if [1,2,3].any?{|position| !values_hash_from_param.has_key?(position)}
164
- max_position = extract_max_param_for_multiparameter_attributes(values_hash_from_param, 6)
165
- # If Date bits were provided but blank, then return nil
166
- return nil if (1..3).any? {|position| values_hash_from_param[position].blank?}
66
+ pairs.each do |(multiparameter_name, value)|
67
+ attribute_name = multiparameter_name.split("(").first
68
+ attributes[attribute_name] ||= {}
167
69
 
168
- set_values = (1..max_position).collect{|position| values_hash_from_param[position] }
169
- # If Time bits are not there, then default to 0
170
- (3..5).each {|i| set_values[i] = set_values[i].blank? ? 0 : set_values[i]}
171
- instantiate_time_object(name, set_values)
172
- end
70
+ parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
71
+ attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
72
+ end
173
73
 
174
- def read_date_parameter_value(name, values_hash_from_param)
175
- return nil if (1..3).any? {|position| values_hash_from_param[position].blank?}
176
- set_values = [values_hash_from_param[1], values_hash_from_param[2], values_hash_from_param[3]]
177
- begin
178
- Date.new(*set_values)
179
- rescue ArgumentError # if Date.new raises an exception on an invalid date
180
- instantiate_time_object(name, set_values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
74
+ attributes
181
75
  end
182
- end
183
76
 
184
- def read_other_parameter_value(klass, name, values_hash_from_param)
185
- max_position = extract_max_param_for_multiparameter_attributes(values_hash_from_param)
186
- values = (1..max_position).collect do |position|
187
- raise "Missing Parameter" if !values_hash_from_param.has_key?(position)
188
- values_hash_from_param[position]
77
+ def type_cast_attribute_value(multiparameter_name, value)
78
+ multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
189
79
  end
190
- klass.new(*values)
191
- end
192
80
 
193
- def extract_max_param_for_multiparameter_attributes(values_hash_from_param, upper_cap = 100)
194
- [values_hash_from_param.keys.max,upper_cap].min
195
- end
196
-
197
- def extract_callstack_for_multiparameter_attributes(pairs)
198
- attributes = { }
199
-
200
- pairs.each do |pair|
201
- multiparameter_name, value = pair
202
- attribute_name = multiparameter_name.split("(").first
203
- attributes[attribute_name] = {} unless attributes.include?(attribute_name)
204
-
205
- parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
206
- attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
81
+ def find_parameter_position(multiparameter_name)
82
+ multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
207
83
  end
208
-
209
- attributes
210
- end
211
-
212
- def type_cast_attribute_value(multiparameter_name, value)
213
- multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
214
- end
215
-
216
- def find_parameter_position(multiparameter_name)
217
- multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
218
- end
219
-
220
84
  end
221
85
  end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module AttributeDecorators # :nodoc:
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_attribute :attribute_type_decorations, instance_accessor: false, default: TypeDecorator.new # :internal:
9
+ end
10
+
11
+ module ClassMethods # :nodoc:
12
+ # This method is an internal API used to create class macros such as
13
+ # +serialize+, and features like time zone aware attributes.
14
+ #
15
+ # Used to wrap the type of an attribute in a new type.
16
+ # When the schema for a model is loaded, attributes with the same name as
17
+ # +column_name+ will have their type yielded to the given block. The
18
+ # return value of that block will be used instead.
19
+ #
20
+ # Subsequent calls where +column_name+ and +decorator_name+ are the same
21
+ # will override the previous decorator, not decorate twice. This can be
22
+ # used to create idempotent class macros like +serialize+
23
+ def decorate_attribute_type(column_name, decorator_name, &block)
24
+ matcher = ->(name, _) { name == column_name.to_s }
25
+ key = "_#{column_name}_#{decorator_name}"
26
+ decorate_matching_attribute_types(matcher, key, &block)
27
+ end
28
+
29
+ # This method is an internal API used to create higher level features like
30
+ # time zone aware attributes.
31
+ #
32
+ # When the schema for a model is loaded, +matcher+ will be called for each
33
+ # attribute with its name and type. If the matcher returns a truthy value,
34
+ # the type will then be yielded to the given block, and the return value
35
+ # of that block will replace the type.
36
+ #
37
+ # Subsequent calls to this method with the same value for +decorator_name+
38
+ # will replace the previous decorator, not decorate twice. This can be
39
+ # used to ensure that class macros are idempotent.
40
+ def decorate_matching_attribute_types(matcher, decorator_name, &block)
41
+ reload_schema_from_cache
42
+ decorator_name = decorator_name.to_s
43
+
44
+ # Create new hashes so we don't modify parent classes
45
+ self.attribute_type_decorations = attribute_type_decorations.merge(decorator_name => [matcher, block])
46
+ end
47
+
48
+ private
49
+
50
+ def load_schema!
51
+ super
52
+ attribute_types.each do |name, type|
53
+ decorated_type = attribute_type_decorations.apply(name, type)
54
+ define_attribute(name, decorated_type)
55
+ end
56
+ end
57
+ end
58
+
59
+ class TypeDecorator # :nodoc:
60
+ delegate :clear, to: :@decorations
61
+
62
+ def initialize(decorations = {})
63
+ @decorations = decorations
64
+ end
65
+
66
+ def merge(*args)
67
+ TypeDecorator.new(@decorations.merge(*args))
68
+ end
69
+
70
+ def apply(name, type)
71
+ decorations = decorators_for(name, type)
72
+ decorations.inject(type) do |new_type, block|
73
+ block.call(new_type)
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ def decorators_for(name, type)
80
+ matching(name, type).map(&:last)
81
+ end
82
+
83
+ def matching(name, type)
84
+ @decorations.values.select do |(matcher, _)|
85
+ matcher.call(name, type)
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -1,31 +1,81 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module AttributeMethods
5
+ # = Active Record Attribute Methods Before Type Cast
6
+ #
7
+ # ActiveRecord::AttributeMethods::BeforeTypeCast provides a way to
8
+ # read the value of the attributes before typecasting and deserialization.
9
+ #
10
+ # class Task < ActiveRecord::Base
11
+ # end
12
+ #
13
+ # task = Task.new(id: '1', completed_on: '2012-10-21')
14
+ # task.id # => 1
15
+ # task.completed_on # => Sun, 21 Oct 2012
16
+ #
17
+ # task.attributes_before_type_cast
18
+ # # => {"id"=>"1", "completed_on"=>"2012-10-21", ... }
19
+ # task.read_attribute_before_type_cast('id') # => "1"
20
+ # task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
21
+ #
22
+ # In addition to #read_attribute_before_type_cast and #attributes_before_type_cast,
23
+ # it declares a method for all attributes with the <tt>*_before_type_cast</tt>
24
+ # suffix.
25
+ #
26
+ # task.id_before_type_cast # => "1"
27
+ # task.completed_on_before_type_cast # => "2012-10-21"
3
28
  module BeforeTypeCast
4
29
  extend ActiveSupport::Concern
5
30
 
6
31
  included do
7
32
  attribute_method_suffix "_before_type_cast"
33
+ attribute_method_suffix "_came_from_user?"
8
34
  end
9
35
 
36
+ # Returns the value of the attribute identified by +attr_name+ before
37
+ # typecasting and deserialization.
38
+ #
39
+ # class Task < ActiveRecord::Base
40
+ # end
41
+ #
42
+ # task = Task.new(id: '1', completed_on: '2012-10-21')
43
+ # task.read_attribute('id') # => 1
44
+ # task.read_attribute_before_type_cast('id') # => '1'
45
+ # task.read_attribute('completed_on') # => Sun, 21 Oct 2012
46
+ # task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
47
+ # task.read_attribute_before_type_cast(:completed_on) # => "2012-10-21"
10
48
  def read_attribute_before_type_cast(attr_name)
11
- @attributes[attr_name]
49
+ sync_with_transaction_state if @transaction_state&.finalized?
50
+ @attributes[attr_name.to_s].value_before_type_cast
12
51
  end
13
52
 
14
53
  # Returns a hash of attributes before typecasting and deserialization.
54
+ #
55
+ # class Task < ActiveRecord::Base
56
+ # end
57
+ #
58
+ # task = Task.new(title: nil, is_done: true, completed_on: '2012-10-21')
59
+ # task.attributes
60
+ # # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>Sun, 21 Oct 2012, "created_at"=>nil, "updated_at"=>nil}
61
+ # task.attributes_before_type_cast
62
+ # # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil}
15
63
  def attributes_before_type_cast
16
- @attributes
64
+ sync_with_transaction_state if @transaction_state&.finalized?
65
+ @attributes.values_before_type_cast
17
66
  end
18
67
 
19
68
  private
20
69
 
21
- # Handle *_before_type_cast for method_missing.
22
- def attribute_before_type_cast(attribute_name)
23
- if attribute_name == 'id'
24
- read_attribute_before_type_cast(self.class.primary_key)
25
- else
70
+ # Dispatch target for <tt>*_before_type_cast</tt> attribute methods.
71
+ def attribute_before_type_cast(attribute_name)
26
72
  read_attribute_before_type_cast(attribute_name)
27
73
  end
28
- end
74
+
75
+ def attribute_came_from_user?(attribute_name)
76
+ sync_with_transaction_state if @transaction_state&.finalized?
77
+ @attributes[attribute_name].came_from_user?
78
+ end
29
79
  end
30
80
  end
31
81
  end