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,14 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/filters"
4
+
1
5
  module ActiveRecord
2
6
  module Integration
3
- # Returns a String, which Action Pack uses for constructing an URL to this
4
- # object. The default implementation returns this record's id as a String,
5
- # or nil if this record's unsaved.
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ ##
11
+ # :singleton-method:
12
+ # Indicates the format used to generate the timestamp in the cache key, if
13
+ # versioning is off. Accepts any of the symbols in <tt>Time::DATE_FORMATS</tt>.
14
+ #
15
+ # This is +:usec+, by default.
16
+ class_attribute :cache_timestamp_format, instance_writer: false, default: :usec
17
+
18
+ ##
19
+ # :singleton-method:
20
+ # Indicates whether to use a stable #cache_key method that is accompanied
21
+ # by a changing version in the #cache_version method.
22
+ #
23
+ # This is +true+, by default on Rails 5.2 and above.
24
+ class_attribute :cache_versioning, instance_writer: false, default: false
25
+
26
+ ##
27
+ # :singleton-method:
28
+ # Indicates whether to use a stable #cache_key method that is accompanied
29
+ # by a changing version in the #cache_version method on collections.
30
+ #
31
+ # This is +false+, by default until Rails 6.1.
32
+ class_attribute :collection_cache_versioning, instance_writer: false, default: false
33
+ end
34
+
35
+ # Returns a +String+, which Action Pack uses for constructing a URL to this
36
+ # object. The default implementation returns this record's id as a +String+,
37
+ # or +nil+ if this record's unsaved.
6
38
  #
7
39
  # For example, suppose that you have a User model, and that you have a
8
40
  # <tt>resources :users</tt> route. Normally, +user_path+ will
9
41
  # construct a path with the user object's 'id' in it:
10
42
  #
11
- # user = User.find_by_name('Phusion')
43
+ # user = User.find_by(name: 'Phusion')
12
44
  # user_path(user) # => "/users/1"
13
45
  #
14
46
  # You can override +to_param+ in your model to make +user_path+ construct
@@ -20,30 +52,156 @@ module ActiveRecord
20
52
  # end
21
53
  # end
22
54
  #
23
- # user = User.find_by_name('Phusion')
55
+ # user = User.find_by(name: 'Phusion')
24
56
  # user_path(user) # => "/users/Phusion"
25
57
  def to_param
26
58
  # We can't use alias_method here, because method 'id' optimizes itself on the fly.
27
59
  id && id.to_s # Be sure to stringify the id for routes
28
60
  end
29
61
 
30
- # Returns a cache key that can be used to identify this record.
31
- #
32
- # ==== Examples
62
+ # Returns a stable cache key that can be used to identify this record.
33
63
  #
34
64
  # Product.new.cache_key # => "products/new"
35
- # Product.find(5).cache_key # => "products/5" (updated_at not available)
36
- # Person.find(5).cache_key # => "people/5-20071224150000" (updated_at available)
65
+ # Product.find(5).cache_key # => "products/5"
66
+ #
67
+ # If ActiveRecord::Base.cache_versioning is turned off, as it was in Rails 5.1 and earlier,
68
+ # the cache key will also include a version.
69
+ #
70
+ # Product.cache_versioning = false
71
+ # Product.find(5).cache_key # => "products/5-20071224150000" (updated_at available)
37
72
  def cache_key
38
- case
39
- when new_record?
40
- "#{self.class.model_name.cache_key}/new"
41
- when timestamp = self[:updated_at]
42
- timestamp = timestamp.utc.to_s(:number)
43
- "#{self.class.model_name.cache_key}/#{id}-#{timestamp}"
73
+ if new_record?
74
+ "#{model_name.cache_key}/new"
75
+ else
76
+ if cache_version
77
+ "#{model_name.cache_key}/#{id}"
78
+ else
79
+ timestamp = max_updated_column_timestamp
80
+
81
+ if timestamp
82
+ timestamp = timestamp.utc.to_s(cache_timestamp_format)
83
+ "#{model_name.cache_key}/#{id}-#{timestamp}"
84
+ else
85
+ "#{model_name.cache_key}/#{id}"
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ # Returns a cache version that can be used together with the cache key to form
92
+ # a recyclable caching scheme. By default, the #updated_at column is used for the
93
+ # cache_version, but this method can be overwritten to return something else.
94
+ #
95
+ # Note, this method will return nil if ActiveRecord::Base.cache_versioning is set to
96
+ # +false+ (which it is by default until Rails 6.0).
97
+ def cache_version
98
+ return unless cache_versioning
99
+
100
+ if has_attribute?("updated_at")
101
+ timestamp = updated_at_before_type_cast
102
+ if can_use_fast_cache_version?(timestamp)
103
+ raw_timestamp_to_cache_version(timestamp)
104
+ elsif timestamp = updated_at
105
+ timestamp.utc.to_s(cache_timestamp_format)
106
+ end
107
+ else
108
+ if self.class.has_attribute?("updated_at")
109
+ raise ActiveModel::MissingAttributeError, "missing attribute: updated_at"
110
+ end
111
+ end
112
+ end
113
+
114
+ # Returns a cache key along with the version.
115
+ def cache_key_with_version
116
+ if version = cache_version
117
+ "#{cache_key}-#{version}"
44
118
  else
45
- "#{self.class.model_name.cache_key}/#{id}"
119
+ cache_key
46
120
  end
47
121
  end
122
+
123
+ module ClassMethods
124
+ # Defines your model's +to_param+ method to generate "pretty" URLs
125
+ # using +method_name+, which can be any attribute or method that
126
+ # responds to +to_s+.
127
+ #
128
+ # class User < ActiveRecord::Base
129
+ # to_param :name
130
+ # end
131
+ #
132
+ # user = User.find_by(name: 'Fancy Pants')
133
+ # user.id # => 123
134
+ # user_path(user) # => "/users/123-fancy-pants"
135
+ #
136
+ # Values longer than 20 characters will be truncated. The value
137
+ # is truncated word by word.
138
+ #
139
+ # user = User.find_by(name: 'David Heinemeier Hansson')
140
+ # user.id # => 125
141
+ # user_path(user) # => "/users/125-david-heinemeier"
142
+ #
143
+ # Because the generated param begins with the record's +id+, it is
144
+ # suitable for passing to +find+. In a controller, for example:
145
+ #
146
+ # params[:id] # => "123-fancy-pants"
147
+ # User.find(params[:id]).id # => 123
148
+ def to_param(method_name = nil)
149
+ if method_name.nil?
150
+ super()
151
+ else
152
+ define_method :to_param do
153
+ if (default = super()) &&
154
+ (result = send(method_name).to_s).present? &&
155
+ (param = result.squish.parameterize.truncate(20, separator: /-/, omission: "")).present?
156
+ "#{default}-#{param}"
157
+ else
158
+ default
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc:
165
+ collection.send(:compute_cache_key, timestamp_column)
166
+ end
167
+ end
168
+
169
+ private
170
+ # Detects if the value before type cast
171
+ # can be used to generate a cache_version.
172
+ #
173
+ # The fast cache version only works with a
174
+ # string value directly from the database.
175
+ #
176
+ # We also must check if the timestamp format has been changed
177
+ # or if the timezone is not set to UTC then
178
+ # we cannot apply our transformations correctly.
179
+ def can_use_fast_cache_version?(timestamp)
180
+ timestamp.is_a?(String) &&
181
+ cache_timestamp_format == :usec &&
182
+ default_timezone == :utc &&
183
+ !updated_at_came_from_user?
184
+ end
185
+
186
+ # Converts a raw database string to `:usec`
187
+ # format.
188
+ #
189
+ # Example:
190
+ #
191
+ # timestamp = "2018-10-15 20:02:15.266505"
192
+ # raw_timestamp_to_cache_version(timestamp)
193
+ # # => "20181015200215266505"
194
+ #
195
+ # PostgreSQL truncates trailing zeros,
196
+ # https://github.com/postgres/postgres/commit/3e1beda2cde3495f41290e1ece5d544525810214
197
+ # to account for this we pad the output with zeros
198
+ def raw_timestamp_to_cache_version(timestamp)
199
+ key = timestamp.delete("- :.")
200
+ if key.length < 20
201
+ key.ljust(20, "0")
202
+ else
203
+ key
204
+ end
205
+ end
48
206
  end
49
207
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/scoping/default"
4
+ require "active_record/scoping/named"
5
+
6
+ module ActiveRecord
7
+ # This class is used to create a table that keeps track of values and keys such
8
+ # as which environment migrations were run in.
9
+ class InternalMetadata < ActiveRecord::Base # :nodoc:
10
+ class << self
11
+ def _internal?
12
+ true
13
+ end
14
+
15
+ def primary_key
16
+ "key"
17
+ end
18
+
19
+ def table_name
20
+ "#{table_name_prefix}#{internal_metadata_table_name}#{table_name_suffix}"
21
+ end
22
+
23
+ def []=(key, value)
24
+ find_or_initialize_by(key: key).update!(value: value)
25
+ end
26
+
27
+ def [](key)
28
+ where(key: key).pluck(:value).first
29
+ end
30
+
31
+ def table_exists?
32
+ connection.table_exists?(table_name)
33
+ end
34
+
35
+ # Creates an internal metadata table with columns +key+ and +value+
36
+ def create_table
37
+ unless table_exists?
38
+ key_options = connection.internal_string_options_for_primary_key
39
+
40
+ connection.create_table(table_name, id: false) do |t|
41
+ t.string :key, key_options
42
+ t.string :value
43
+ t.timestamps
44
+ end
45
+ end
46
+ end
47
+
48
+ def drop_table
49
+ connection.drop_table table_name, if_exists: true
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module LegacyYamlAdapter
5
+ def self.convert(klass, coder)
6
+ return coder unless coder.is_a?(Psych::Coder)
7
+
8
+ case coder["active_record_yaml_version"]
9
+ when 1, 2 then coder
10
+ else
11
+ if coder["attributes"].is_a?(ActiveModel::AttributeSet)
12
+ Rails420.convert(klass, coder)
13
+ else
14
+ Rails41.convert(klass, coder)
15
+ end
16
+ end
17
+ end
18
+
19
+ module Rails420
20
+ def self.convert(klass, coder)
21
+ attribute_set = coder["attributes"]
22
+
23
+ klass.attribute_names.each do |attr_name|
24
+ attribute = attribute_set[attr_name]
25
+ if attribute.type.is_a?(Delegator)
26
+ type_from_klass = klass.type_for_attribute(attr_name)
27
+ attribute_set[attr_name] = attribute.with_type(type_from_klass)
28
+ end
29
+ end
30
+
31
+ coder
32
+ end
33
+ end
34
+
35
+ module Rails41
36
+ def self.convert(klass, coder)
37
+ attributes = klass.attributes_builder
38
+ .build_from_database(coder["attributes"])
39
+ new_record = coder["attributes"][klass.primary_key].blank?
40
+
41
+ {
42
+ "attributes" => attributes,
43
+ "new_record" => new_record,
44
+ }
45
+ end
46
+ end
47
+ end
48
+ end
@@ -4,12 +4,20 @@ en:
4
4
  #created_at: "Created at"
5
5
  #updated_at: "Updated at"
6
6
 
7
+ # Default error messages
8
+ errors:
9
+ messages:
10
+ required: "must exist"
11
+ taken: "has already been taken"
12
+
7
13
  # Active Record models configuration
8
14
  activerecord:
9
15
  errors:
10
16
  messages:
11
- taken: "has already been taken"
12
17
  record_invalid: "Validation failed: %{errors}"
18
+ restrict_dependent_destroy:
19
+ has_one: "Cannot delete record because a dependent %{record} exists"
20
+ has_many: "Cannot delete record because dependent %{record} exist"
13
21
  # Append your own errors here or at the model/attributes scope.
14
22
 
15
23
  # You can define own errors for models or model attributes.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Locking
3
5
  # == What is Optimistic Locking
@@ -11,7 +13,7 @@ module ActiveRecord
11
13
  #
12
14
  # == Usage
13
15
  #
14
- # Active Records support optimistic locking if the field +lock_version+ is present. Each update to the
16
+ # Active Record supports optimistic locking if the +lock_version+ field is present. Each update to the
15
17
  # record increments the +lock_version+ column and the locking facilities ensure that records instantiated twice
16
18
  # will let the last one saved raise a +StaleObjectError+ if the first was also updated. Example:
17
19
  #
@@ -22,7 +24,7 @@ module ActiveRecord
22
24
  # p1.save
23
25
  #
24
26
  # p2.first_name = "should fail"
25
- # p2.save # Raises a ActiveRecord::StaleObjectError
27
+ # p2.save # Raises an ActiveRecord::StaleObjectError
26
28
  #
27
29
  # Optimistic locking will also check for stale data when objects are destroyed. Example:
28
30
  #
@@ -32,7 +34,7 @@ module ActiveRecord
32
34
  # p1.first_name = "Michael"
33
35
  # p1.save
34
36
  #
35
- # p2.destroy # Raises a ActiveRecord::StaleObjectError
37
+ # p2.destroy # Raises an ActiveRecord::StaleObjectError
36
38
  #
37
39
  # You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging,
38
40
  # or otherwise apply the business logic needed to resolve the conflict.
@@ -40,17 +42,18 @@ module ActiveRecord
40
42
  # This locking mechanism will function inside a single Ruby process. To make it work across all
41
43
  # web requests, the recommended approach is to add +lock_version+ as a hidden field to your form.
42
44
  #
43
- # You must ensure that your database schema defaults the +lock_version+ column to 0.
44
- #
45
45
  # This behavior can be turned off by setting <tt>ActiveRecord::Base.lock_optimistically = false</tt>.
46
- # To override the name of the +lock_version+ column, invoke the <tt>set_locking_column</tt> method.
47
- # This method uses the same syntax as <tt>set_table_name</tt>
46
+ # To override the name of the +lock_version+ column, set the <tt>locking_column</tt> class attribute:
47
+ #
48
+ # class Person < ActiveRecord::Base
49
+ # self.locking_column = :lock_person
50
+ # end
51
+ #
48
52
  module Optimistic
49
53
  extend ActiveSupport::Concern
50
54
 
51
55
  included do
52
- cattr_accessor :lock_optimistically, :instance_writer => false
53
- self.lock_optimistically = true
56
+ class_attribute :lock_optimistically, instance_writer: false, default: true
54
57
  end
55
58
 
56
59
  def locking_enabled? #:nodoc:
@@ -58,125 +61,136 @@ module ActiveRecord
58
61
  end
59
62
 
60
63
  private
61
- def increment_lock
62
- lock_col = self.class.locking_column
63
- previous_lock_value = send(lock_col).to_i
64
- send(lock_col + '=', previous_lock_value + 1)
64
+ def _create_record(attribute_names = self.attribute_names)
65
+ if locking_enabled?
66
+ # We always want to persist the locking version, even if we don't detect
67
+ # a change from the default, since the database might have no default
68
+ attribute_names |= [self.class.locking_column]
69
+ end
70
+ super
65
71
  end
66
72
 
67
- def update(attribute_names = @attributes.keys) #:nodoc:
68
- return super unless locking_enabled?
69
- return 0 if attribute_names.empty?
70
-
71
- lock_col = self.class.locking_column
72
- previous_lock_value = send(lock_col).to_i
73
- increment_lock
73
+ def _touch_row(attribute_names, time)
74
+ @_touch_attr_names << self.class.locking_column if locking_enabled?
75
+ super
76
+ end
74
77
 
75
- attribute_names += [lock_col]
76
- attribute_names.uniq!
78
+ def _update_row(attribute_names, attempted_action = "update")
79
+ return super unless locking_enabled?
77
80
 
78
81
  begin
79
- relation = self.class.unscoped
82
+ locking_column = self.class.locking_column
83
+ previous_lock_value = read_attribute_before_type_cast(locking_column)
84
+ attribute_names << locking_column
80
85
 
81
- stmt = relation.where(
82
- relation.table[self.class.primary_key].eq(id).and(
83
- relation.table[lock_col].eq(quote_value(previous_lock_value))
84
- )
85
- ).arel.compile_update(arel_attributes_values(false, false, attribute_names))
86
+ self[locking_column] += 1
86
87
 
87
- affected_rows = connection.update stmt
88
+ affected_rows = self.class._update_record(
89
+ attributes_with_values(attribute_names),
90
+ @primary_key => id_in_database,
91
+ locking_column => previous_lock_value
92
+ )
88
93
 
89
- unless affected_rows == 1
90
- raise ActiveRecord::StaleObjectError.new(self, "update")
94
+ if affected_rows != 1
95
+ raise ActiveRecord::StaleObjectError.new(self, attempted_action)
91
96
  end
92
97
 
93
98
  affected_rows
94
99
 
95
- # If something went wrong, revert the version.
100
+ # If something went wrong, revert the locking_column value.
96
101
  rescue Exception
97
- send(lock_col + '=', previous_lock_value)
102
+ self[locking_column] = previous_lock_value.to_i
98
103
  raise
99
104
  end
100
105
  end
101
106
 
102
- def destroy #:nodoc:
107
+ def destroy_row
103
108
  return super unless locking_enabled?
104
109
 
105
- if persisted?
106
- table = self.class.arel_table
107
- lock_col = self.class.locking_column
108
- predicate = table[self.class.primary_key].eq(id).
109
- and(table[lock_col].eq(send(lock_col).to_i))
110
+ locking_column = self.class.locking_column
110
111
 
111
- affected_rows = self.class.unscoped.where(predicate).delete_all
112
+ affected_rows = self.class._delete_record(
113
+ @primary_key => id_in_database,
114
+ locking_column => read_attribute_before_type_cast(locking_column)
115
+ )
112
116
 
113
- unless affected_rows == 1
114
- raise ActiveRecord::StaleObjectError.new(self, "destroy")
115
- end
117
+ if affected_rows != 1
118
+ raise ActiveRecord::StaleObjectError.new(self, "destroy")
116
119
  end
117
120
 
118
- @destroyed = true
119
- freeze
121
+ affected_rows
120
122
  end
121
123
 
122
- module ClassMethods
123
- DEFAULT_LOCKING_COLUMN = 'lock_version'
124
+ module ClassMethods
125
+ DEFAULT_LOCKING_COLUMN = "lock_version"
124
126
 
125
- # Returns true if the +lock_optimistically+ flag is set to true
126
- # (which it is, by default) and the table includes the
127
- # +locking_column+ column (defaults to +lock_version+).
128
- def locking_enabled?
129
- lock_optimistically && columns_hash[locking_column]
130
- end
127
+ # Returns true if the +lock_optimistically+ flag is set to true
128
+ # (which it is, by default) and the table includes the
129
+ # +locking_column+ column (defaults to +lock_version+).
130
+ def locking_enabled?
131
+ lock_optimistically && columns_hash[locking_column]
132
+ end
131
133
 
132
- def locking_column=(value)
133
- @original_locking_column = @locking_column if defined?(@locking_column)
134
- @locking_column = value.to_s
135
- end
134
+ # Set the column to use for optimistic locking. Defaults to +lock_version+.
135
+ def locking_column=(value)
136
+ reload_schema_from_cache
137
+ @locking_column = value.to_s
138
+ end
136
139
 
137
- # Set the column to use for optimistic locking. Defaults to +lock_version+.
138
- def set_locking_column(value = nil, &block)
139
- deprecated_property_setter :locking_column, value, block
140
- end
140
+ # The version column used for optimistic locking. Defaults to +lock_version+.
141
+ def locking_column
142
+ @locking_column = DEFAULT_LOCKING_COLUMN unless defined?(@locking_column)
143
+ @locking_column
144
+ end
141
145
 
142
- # The version column used for optimistic locking. Defaults to +lock_version+.
143
- def locking_column
144
- reset_locking_column unless defined?(@locking_column)
145
- @locking_column
146
- end
146
+ # Reset the column used for optimistic locking back to the +lock_version+ default.
147
+ def reset_locking_column
148
+ self.locking_column = DEFAULT_LOCKING_COLUMN
149
+ end
147
150
 
148
- def original_locking_column #:nodoc:
149
- deprecated_original_property_getter :locking_column
150
- end
151
+ # Make sure the lock version column gets updated when counters are
152
+ # updated.
153
+ def update_counters(id, counters)
154
+ counters = counters.merge(locking_column => 1) if locking_enabled?
155
+ super
156
+ end
151
157
 
152
- # Quote the column name used for optimistic locking.
153
- def quoted_locking_column
154
- connection.quote_column_name(locking_column)
158
+ private
159
+
160
+ # We need to apply this decorator here, rather than on module inclusion. The closure
161
+ # created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the
162
+ # sub class being decorated. As such, changes to `lock_optimistically`, or
163
+ # `locking_column` would not be picked up.
164
+ def inherited(subclass)
165
+ subclass.class_eval do
166
+ is_lock_column = ->(name, _) { lock_optimistically && name == locking_column }
167
+ decorate_matching_attribute_types(is_lock_column, "_optimistic_locking") do |type|
168
+ LockingType.new(type)
169
+ end
170
+ end
171
+ super
172
+ end
155
173
  end
174
+ end
156
175
 
157
- # Reset the column used for optimistic locking back to the +lock_version+ default.
158
- def reset_locking_column
159
- self.locking_column = DEFAULT_LOCKING_COLUMN
160
- end
176
+ # In de/serialize we change `nil` to 0, so that we can allow passing
177
+ # `nil` values to `lock_version`, and not result in `ActiveRecord::StaleObjectError`
178
+ # during update record.
179
+ class LockingType < DelegateClass(Type::Value) # :nodoc:
180
+ def deserialize(value)
181
+ super.to_i
182
+ end
161
183
 
162
- # Make sure the lock version column gets updated when counters are
163
- # updated.
164
- def update_counters(id, counters)
165
- counters = counters.merge(locking_column => 1) if locking_enabled?
166
- super
167
- end
184
+ def serialize(value)
185
+ super.to_i
186
+ end
168
187
 
169
- # If the locking column has no default value set,
170
- # start the lock version at zero. Note we can't use
171
- # <tt>locking_enabled?</tt> at this point as
172
- # <tt>@attributes</tt> may not have been initialized yet.
173
- def initialize_attributes(attributes, options = {}) #:nodoc:
174
- if attributes.key?(locking_column) && lock_optimistically
175
- attributes[locking_column] ||= 0
176
- end
188
+ def init_with(coder)
189
+ __setobj__(coder["subtype"])
190
+ end
177
191
 
178
- attributes
179
- end
192
+ def encode_with(coder)
193
+ coder["subtype"] = __getobj__
180
194
  end
181
195
  end
182
196
  end