activerecord 4.2.9 → 6.1.4.1

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

Potentially problematic release.


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

Files changed (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +964 -1382
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +15 -14
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +266 -251
  8. data/lib/active_record/association_relation.rb +40 -15
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +162 -69
  11. data/lib/active_record/associations/association_scope.rb +105 -130
  12. data/lib/active_record/associations/belongs_to_association.rb +83 -65
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  14. data/lib/active_record/associations/builder/association.rb +57 -43
  15. data/lib/active_record/associations/builder/belongs_to.rb +74 -57
  16. data/lib/active_record/associations/builder/collection_association.rb +15 -37
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +49 -66
  18. data/lib/active_record/associations/builder/has_many.rb +13 -5
  19. data/lib/active_record/associations/builder/has_one.rb +44 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +148 -287
  22. data/lib/active_record/associations/collection_proxy.rb +252 -150
  23. data/lib/active_record/associations/foreign_association.rb +23 -1
  24. data/lib/active_record/associations/has_many_association.rb +56 -98
  25. data/lib/active_record/associations/has_many_through_association.rb +68 -89
  26. data/lib/active_record/associations/has_one_association.rb +73 -47
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +54 -81
  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 +174 -169
  32. data/lib/active_record/associations/preloader/association.rb +108 -115
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +97 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -39
  36. data/lib/active_record/associations/through_association.rb +39 -19
  37. data/lib/active_record/associations.rb +1845 -1598
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +18 -10
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -148
  41. data/lib/active_record/attribute_methods/primary_key.rb +93 -83
  42. data/lib/active_record/attribute_methods/query.rb +8 -10
  43. data/lib/active_record/attribute_methods/read.rb +19 -79
  44. data/lib/active_record/attribute_methods/serialization.rb +49 -24
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +55 -36
  46. data/lib/active_record/attribute_methods/write.rb +24 -55
  47. data/lib/active_record/attribute_methods.rb +149 -154
  48. data/lib/active_record/attributes.rb +234 -78
  49. data/lib/active_record/autosave_association.rb +133 -60
  50. data/lib/active_record/base.rb +46 -46
  51. data/lib/active_record/callbacks.rb +234 -79
  52. data/lib/active_record/coders/json.rb +3 -1
  53. data/lib/active_record/coders/yaml_column.rb +34 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -323
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +292 -124
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +177 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +8 -6
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +473 -255
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +869 -286
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +257 -91
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +483 -230
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +557 -640
  67. data/lib/active_record/connection_adapters/column.rb +67 -40
  68. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  69. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +194 -0
  72. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +80 -192
  80. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  81. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -160
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -58
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -19
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  109. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
  110. data/lib/active_record/connection_adapters/postgresql/quoting.rb +145 -48
  111. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  112. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  114. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +496 -298
  116. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  117. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  118. data/lib/active_record/connection_adapters/postgresql_adapter.rb +588 -375
  119. data/lib/active_record/connection_adapters/schema_cache.rb +167 -29
  120. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  121. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  122. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  123. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -373
  129. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  130. data/lib/active_record/connection_adapters.rb +52 -0
  131. data/lib/active_record/connection_handling.rb +314 -41
  132. data/lib/active_record/core.rb +458 -241
  133. data/lib/active_record/counter_cache.rb +70 -49
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  135. data/lib/active_record/database_configurations/database_config.rb +80 -0
  136. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  137. data/lib/active_record/database_configurations/url_config.rb +53 -0
  138. data/lib/active_record/database_configurations.rb +272 -0
  139. data/lib/active_record/delegated_type.rb +209 -0
  140. data/lib/active_record/destroy_association_async_job.rb +36 -0
  141. data/lib/active_record/dynamic_matchers.rb +87 -106
  142. data/lib/active_record/enum.rb +211 -92
  143. data/lib/active_record/errors.rb +224 -54
  144. data/lib/active_record/explain.rb +27 -11
  145. data/lib/active_record/explain_registry.rb +4 -2
  146. data/lib/active_record/explain_subscriber.rb +10 -5
  147. data/lib/active_record/fixture_set/file.rb +33 -14
  148. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  149. data/lib/active_record/fixture_set/render_context.rb +17 -0
  150. data/lib/active_record/fixture_set/table_row.rb +152 -0
  151. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  152. data/lib/active_record/fixtures.rb +275 -500
  153. data/lib/active_record/gem_version.rb +6 -4
  154. data/lib/active_record/inheritance.rb +175 -110
  155. data/lib/active_record/insert_all.rb +212 -0
  156. data/lib/active_record/integration.rb +121 -29
  157. data/lib/active_record/internal_metadata.rb +62 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +27 -5
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +98 -92
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +93 -31
  163. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector.rb +77 -0
  166. data/lib/active_record/migration/command_recorder.rb +185 -90
  167. data/lib/active_record/migration/compatibility.rb +295 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +673 -325
  170. data/lib/active_record/model_schema.rb +418 -113
  171. data/lib/active_record/nested_attributes.rb +263 -224
  172. data/lib/active_record/no_touching.rb +15 -2
  173. data/lib/active_record/null_relation.rb +24 -38
  174. data/lib/active_record/persistence.rb +572 -136
  175. data/lib/active_record/query_cache.rb +29 -23
  176. data/lib/active_record/querying.rb +50 -31
  177. data/lib/active_record/railtie.rb +170 -51
  178. data/lib/active_record/railties/console_sandbox.rb +3 -3
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +523 -199
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +454 -291
  183. data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
  184. data/lib/active_record/relation/batches.rb +217 -59
  185. data/lib/active_record/relation/calculations.rb +324 -249
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +316 -242
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +95 -103
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -26
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  192. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  193. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
  194. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  195. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  196. data/lib/active_record/relation/predicate_builder.rb +136 -122
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -413
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +18 -20
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -343
  203. data/lib/active_record/result.rb +91 -47
  204. data/lib/active_record/runtime_registry.rb +6 -4
  205. data/lib/active_record/sanitization.rb +134 -122
  206. data/lib/active_record/schema.rb +21 -24
  207. data/lib/active_record/schema_dumper.rb +141 -92
  208. data/lib/active_record/schema_migration.rb +24 -23
  209. data/lib/active_record/scoping/default.rb +96 -83
  210. data/lib/active_record/scoping/named.rb +78 -36
  211. data/lib/active_record/scoping.rb +45 -27
  212. data/lib/active_record/secure_token.rb +48 -0
  213. data/lib/active_record/serialization.rb +8 -6
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +89 -36
  216. data/lib/active_record/store.rb +128 -43
  217. data/lib/active_record/suppressor.rb +61 -0
  218. data/lib/active_record/table_metadata.rb +81 -0
  219. data/lib/active_record/tasks/database_tasks.rb +364 -130
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +67 -113
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +86 -49
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +287 -0
  225. data/lib/active_record/timestamp.rb +86 -43
  226. data/lib/active_record/touch_later.rb +65 -0
  227. data/lib/active_record/transactions.rb +182 -163
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  230. data/lib/active_record/type/date.rb +4 -45
  231. data/lib/active_record/type/date_time.rb +4 -49
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  234. data/lib/active_record/type/internal/timezone.rb +17 -0
  235. data/lib/active_record/type/json.rb +30 -0
  236. data/lib/active_record/type/serialized.rb +27 -15
  237. data/lib/active_record/type/text.rb +2 -2
  238. data/lib/active_record/type/time.rb +21 -16
  239. data/lib/active_record/type/type_map.rb +16 -19
  240. data/lib/active_record/type/unsigned_integer.rb +9 -8
  241. data/lib/active_record/type.rb +84 -23
  242. data/lib/active_record/type_caster/connection.rb +33 -0
  243. data/lib/active_record/type_caster/map.rb +23 -0
  244. data/lib/active_record/type_caster.rb +9 -0
  245. data/lib/active_record/validations/absence.rb +25 -0
  246. data/lib/active_record/validations/associated.rb +12 -4
  247. data/lib/active_record/validations/length.rb +26 -0
  248. data/lib/active_record/validations/numericality.rb +35 -0
  249. data/lib/active_record/validations/presence.rb +14 -13
  250. data/lib/active_record/validations/uniqueness.rb +63 -56
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +42 -29
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes/and.rb +32 -0
  269. data/lib/arel/nodes/ascending.rb +23 -0
  270. data/lib/arel/nodes/binary.rb +126 -0
  271. data/lib/arel/nodes/bind_param.rb +44 -0
  272. data/lib/arel/nodes/case.rb +55 -0
  273. data/lib/arel/nodes/casted.rb +62 -0
  274. data/lib/arel/nodes/comment.rb +29 -0
  275. data/lib/arel/nodes/count.rb +12 -0
  276. data/lib/arel/nodes/delete_statement.rb +45 -0
  277. data/lib/arel/nodes/descending.rb +23 -0
  278. data/lib/arel/nodes/equality.rb +15 -0
  279. data/lib/arel/nodes/extract.rb +24 -0
  280. data/lib/arel/nodes/false.rb +16 -0
  281. data/lib/arel/nodes/full_outer_join.rb +8 -0
  282. data/lib/arel/nodes/function.rb +44 -0
  283. data/lib/arel/nodes/grouping.rb +11 -0
  284. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  285. data/lib/arel/nodes/in.rb +15 -0
  286. data/lib/arel/nodes/infix_operation.rb +92 -0
  287. data/lib/arel/nodes/inner_join.rb +8 -0
  288. data/lib/arel/nodes/insert_statement.rb +37 -0
  289. data/lib/arel/nodes/join_source.rb +20 -0
  290. data/lib/arel/nodes/matches.rb +18 -0
  291. data/lib/arel/nodes/named_function.rb +23 -0
  292. data/lib/arel/nodes/node.rb +51 -0
  293. data/lib/arel/nodes/node_expression.rb +13 -0
  294. data/lib/arel/nodes/ordering.rb +27 -0
  295. data/lib/arel/nodes/outer_join.rb +8 -0
  296. data/lib/arel/nodes/over.rb +15 -0
  297. data/lib/arel/nodes/regexp.rb +16 -0
  298. data/lib/arel/nodes/right_outer_join.rb +8 -0
  299. data/lib/arel/nodes/select_core.rb +67 -0
  300. data/lib/arel/nodes/select_statement.rb +41 -0
  301. data/lib/arel/nodes/sql_literal.rb +19 -0
  302. data/lib/arel/nodes/string_join.rb +11 -0
  303. data/lib/arel/nodes/table_alias.rb +31 -0
  304. data/lib/arel/nodes/terminal.rb +16 -0
  305. data/lib/arel/nodes/true.rb +16 -0
  306. data/lib/arel/nodes/unary.rb +44 -0
  307. data/lib/arel/nodes/unary_operation.rb +20 -0
  308. data/lib/arel/nodes/unqualified_column.rb +22 -0
  309. data/lib/arel/nodes/update_statement.rb +41 -0
  310. data/lib/arel/nodes/values_list.rb +9 -0
  311. data/lib/arel/nodes/window.rb +126 -0
  312. data/lib/arel/nodes/with.rb +11 -0
  313. data/lib/arel/nodes.rb +70 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors/dot.rb +308 -0
  321. data/lib/arel/visitors/mysql.rb +93 -0
  322. data/lib/arel/visitors/postgresql.rb +120 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +899 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors.rb +13 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +54 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
  332. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -4
  334. data/lib/rails/generators/active_record/migration.rb +35 -1
  335. data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  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} +0 -0
  339. data/lib/rails/generators/active_record.rb +7 -5
  340. metadata +172 -65
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  348. data/lib/active_record/attribute.rb +0 -163
  349. data/lib/active_record/attribute_decorators.rb +0 -66
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/attribute_set.rb +0 -81
  352. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  353. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  354. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  355. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  356. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  357. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  358. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  359. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  360. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  361. data/lib/active_record/type/big_integer.rb +0 -13
  362. data/lib/active_record/type/binary.rb +0 -50
  363. data/lib/active_record/type/boolean.rb +0 -31
  364. data/lib/active_record/type/decimal.rb +0 -64
  365. data/lib/active_record/type/decorator.rb +0 -14
  366. data/lib/active_record/type/float.rb +0 -19
  367. data/lib/active_record/type/integer.rb +0 -59
  368. data/lib/active_record/type/mutable.rb +0 -16
  369. data/lib/active_record/type/numeric.rb +0 -36
  370. data/lib/active_record/type/string.rb +0 -40
  371. data/lib/active_record/type/time_value.rb +0 -38
  372. data/lib/active_record/type/value.rb +0 -110
  373. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  374. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,6 +1,4 @@
1
- require 'active_support/core_ext/array'
2
- require 'active_support/core_ext/hash/except'
3
- require 'active_support/core_ext/kernel/singleton_class'
1
+ # frozen_string_literal: true
4
2
 
5
3
  module ActiveRecord
6
4
  # = Active Record \Named \Scopes
@@ -9,7 +7,7 @@ module ActiveRecord
9
7
  extend ActiveSupport::Concern
10
8
 
11
9
  module ClassMethods
12
- # Returns an <tt>ActiveRecord::Relation</tt> scope object.
10
+ # Returns an ActiveRecord::Relation scope object.
13
11
  #
14
12
  # posts = Post.all
15
13
  # posts.size # Fires "select count(*) from posts" and returns the count
@@ -20,32 +18,49 @@ module ActiveRecord
20
18
  # fruits = fruits.limit(10) if limited?
21
19
  #
22
20
  # You can define a scope that applies to all finders using
23
- # <tt>ActiveRecord::Base.default_scope</tt>.
21
+ # {default_scope}[rdoc-ref:Scoping::Default::ClassMethods#default_scope].
24
22
  def all
25
- if current_scope
26
- current_scope.clone
23
+ scope = current_scope
24
+
25
+ if scope
26
+ if self == scope.klass
27
+ scope.clone
28
+ else
29
+ relation.merge!(scope)
30
+ end
27
31
  else
28
32
  default_scoped
29
33
  end
30
34
  end
31
35
 
32
- def default_scoped # :nodoc:
33
- relation.merge(build_default_scope)
36
+ def scope_for_association(scope = relation) # :nodoc:
37
+ if current_scope&.empty_scope?
38
+ scope
39
+ else
40
+ default_scoped(scope)
41
+ end
34
42
  end
35
43
 
36
- # Collects attributes from scopes that should be applied when creating
37
- # an AR instance for the particular class this is called on.
38
- def scope_attributes # :nodoc:
39
- all.scope_for_create
44
+ # Returns a scope for the model with default scopes.
45
+ def default_scoped(scope = relation)
46
+ build_default_scope(scope) || scope
40
47
  end
41
48
 
42
- # Are there default attributes associated with this scope?
43
- def scope_attributes? # :nodoc:
44
- current_scope || default_scopes.any?
49
+ def default_extensions # :nodoc:
50
+ if scope = scope_for_association || build_default_scope
51
+ scope.extensions
52
+ else
53
+ []
54
+ end
45
55
  end
46
56
 
47
- # Adds a class method for retrieving and querying objects. A \scope
48
- # represents a narrowing of a database query, such as
57
+ # Adds a class method for retrieving and querying objects.
58
+ # The method is intended to return an ActiveRecord::Relation
59
+ # object, which is composable with other scopes.
60
+ # If it returns +nil+ or +false+, an
61
+ # {all}[rdoc-ref:Scoping::Named::ClassMethods#all] scope is returned instead.
62
+ #
63
+ # A \scope represents a narrowing of a database query, such as
49
64
  # <tt>where(color: :red).select('shirts.*').includes(:washing_instructions)</tt>.
50
65
  #
51
66
  # class Shirt < ActiveRecord::Base
@@ -53,14 +68,10 @@ module ActiveRecord
53
68
  # scope :dry_clean_only, -> { joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true) }
54
69
  # end
55
70
  #
56
- # The above calls to +scope+ define class methods <tt>Shirt.red</tt> and
71
+ # The above calls to #scope define class methods <tt>Shirt.red</tt> and
57
72
  # <tt>Shirt.dry_clean_only</tt>. <tt>Shirt.red</tt>, in effect,
58
73
  # represents the query <tt>Shirt.where(color: 'red')</tt>.
59
74
  #
60
- # You should always pass a callable object to the scopes defined
61
- # with +scope+. This ensures that the scope is re-evaluated each
62
- # time it is called.
63
- #
64
75
  # Note that this is simply 'syntactic sugar' for defining an actual
65
76
  # class method:
66
77
  #
@@ -71,14 +82,15 @@ module ActiveRecord
71
82
  # end
72
83
  #
73
84
  # Unlike <tt>Shirt.find(...)</tt>, however, the object returned by
74
- # <tt>Shirt.red</tt> is not an Array; it resembles the association object
75
- # constructed by a +has_many+ declaration. For instance, you can invoke
76
- # <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>,
85
+ # <tt>Shirt.red</tt> is not an Array but an ActiveRecord::Relation,
86
+ # which is composable with other scopes; it resembles the association object
87
+ # constructed by a {has_many}[rdoc-ref:Associations::ClassMethods#has_many]
88
+ # declaration. For instance, you can invoke <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>,
77
89
  # <tt>Shirt.red.where(size: 'small')</tt>. Also, just as with the
78
90
  # association objects, named \scopes act like an Array, implementing
79
91
  # Enumerable; <tt>Shirt.red.each(&block)</tt>, <tt>Shirt.red.first</tt>,
80
92
  # and <tt>Shirt.red.inject(memo, &block)</tt> all behave as if
81
- # <tt>Shirt.red</tt> really was an Array.
93
+ # <tt>Shirt.red</tt> really was an array.
82
94
  #
83
95
  # These named \scopes are composable. For instance,
84
96
  # <tt>Shirt.red.dry_clean_only</tt> will produce all shirts that are
@@ -89,7 +101,8 @@ module ActiveRecord
89
101
  #
90
102
  # All scopes are available as class methods on the ActiveRecord::Base
91
103
  # descendant upon which the \scopes were defined. But they are also
92
- # available to +has_many+ associations. If,
104
+ # available to {has_many}[rdoc-ref:Associations::ClassMethods#has_many]
105
+ # associations. If,
93
106
  #
94
107
  # class Person < ActiveRecord::Base
95
108
  # has_many :shirts
@@ -98,8 +111,8 @@ module ActiveRecord
98
111
  # then <tt>elton.shirts.red.dry_clean_only</tt> will return all of
99
112
  # Elton's red, dry clean only shirts.
100
113
  #
101
- # \Named scopes can also have extensions, just as with +has_many+
102
- # declarations:
114
+ # \Named scopes can also have extensions, just as with
115
+ # {has_many}[rdoc-ref:Associations::ClassMethods#has_many] declarations:
103
116
  #
104
117
  # class Shirt < ActiveRecord::Base
105
118
  # scope :red, -> { where(color: 'red') } do
@@ -140,7 +153,7 @@ module ActiveRecord
140
153
  # Article.featured.titles
141
154
  def scope(name, body, &block)
142
155
  unless body.respond_to?(:call)
143
- raise ArgumentError, 'The scope body needs to be callable.'
156
+ raise ArgumentError, "The scope body needs to be callable."
144
157
  end
145
158
 
146
159
  if dangerous_class_method?(name)
@@ -149,15 +162,44 @@ module ActiveRecord
149
162
  "a class method with the same name."
150
163
  end
151
164
 
152
- extension = Module.new(&block) if block
165
+ if method_defined_within?(name, Relation)
166
+ raise ArgumentError, "You tried to define a scope named \"#{name}\" " \
167
+ "on the model \"#{self.name}\", but ActiveRecord::Relation already defined " \
168
+ "an instance method with the same name."
169
+ end
153
170
 
154
- singleton_class.send(:define_method, name) do |*args|
155
- scope = all.scoping { body.call(*args) }
156
- scope = scope.extending(extension) if extension
171
+ valid_scope_name?(name)
172
+ extension = Module.new(&block) if block
157
173
 
158
- scope || all
174
+ if body.respond_to?(:to_proc)
175
+ singleton_class.define_method(name) do |*args|
176
+ scope = all._exec_scope(*args, &body)
177
+ scope = scope.extending(extension) if extension
178
+ scope
179
+ end
180
+ else
181
+ singleton_class.define_method(name) do |*args|
182
+ scope = body.call(*args) || all
183
+ scope = scope.extending(extension) if extension
184
+ scope
185
+ end
159
186
  end
187
+ singleton_class.send(:ruby2_keywords, name) if respond_to?(:ruby2_keywords, true)
188
+
189
+ generate_relation_method(name)
160
190
  end
191
+
192
+ private
193
+ def singleton_method_added(name)
194
+ generate_relation_method(name) if Kernel.respond_to?(name) && !ActiveRecord::Relation.method_defined?(name)
195
+ end
196
+
197
+ def valid_scope_name?(name)
198
+ if respond_to?(name, true) && logger
199
+ logger.warn "Creating scope :#{name}. " \
200
+ "Overwriting existing method #{self.name}.#{name}."
201
+ end
202
+ end
161
203
  end
162
204
  end
163
205
  end
@@ -1,4 +1,6 @@
1
- require 'active_support/per_thread_registry'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/per_thread_registry"
2
4
 
3
5
  module ActiveRecord
4
6
  module Scoping
@@ -9,25 +11,35 @@ module ActiveRecord
9
11
  include Named
10
12
  end
11
13
 
12
- module ClassMethods
13
- def current_scope #:nodoc:
14
- ScopeRegistry.value_for(:current_scope, base_class.to_s)
14
+ module ClassMethods # :nodoc:
15
+ # Collects attributes from scopes that should be applied when creating
16
+ # an AR instance for the particular class this is called on.
17
+ def scope_attributes
18
+ all.scope_for_create
19
+ end
20
+
21
+ # Are there attributes associated with this scope?
22
+ def scope_attributes?
23
+ current_scope
24
+ end
25
+
26
+ def current_scope(skip_inherited_scope = false)
27
+ ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope)
15
28
  end
16
29
 
17
- def current_scope=(scope) #:nodoc:
18
- ScopeRegistry.set_value_for(:current_scope, base_class.to_s, scope)
30
+ def current_scope=(scope)
31
+ ScopeRegistry.set_value_for(:current_scope, self, scope)
19
32
  end
20
33
  end
21
34
 
22
- def populate_with_current_scope_attributes
35
+ def populate_with_current_scope_attributes # :nodoc:
23
36
  return unless self.class.scope_attributes?
24
37
 
25
- self.class.scope_attributes.each do |att,value|
26
- send("#{att}=", value) if respond_to?("#{att}=")
27
- end
38
+ attributes = self.class.scope_attributes
39
+ _assign_attributes(attributes) if attributes.any?
28
40
  end
29
41
 
30
- def initialize_internals_callback
42
+ def initialize_internals_callback # :nodoc:
31
43
  super
32
44
  populate_with_current_scope_attributes
33
45
  end
@@ -42,18 +54,18 @@ module ActiveRecord
42
54
  # following code:
43
55
  #
44
56
  # registry = ActiveRecord::Scoping::ScopeRegistry
45
- # registry.set_value_for(:current_scope, "Board", some_new_scope)
57
+ # registry.set_value_for(:current_scope, Board, some_new_scope)
46
58
  #
47
59
  # Now when you run:
48
60
  #
49
- # registry.value_for(:current_scope, "Board")
61
+ # registry.value_for(:current_scope, Board)
50
62
  #
51
- # You will obtain whatever was defined in +some_new_scope+. The +value_for+
52
- # and +set_value_for+ methods are delegated to the current +ScopeRegistry+
63
+ # You will obtain whatever was defined in +some_new_scope+. The #value_for
64
+ # and #set_value_for methods are delegated to the current ScopeRegistry
53
65
  # object, so the above example code can also be called as:
54
66
  #
55
67
  # ActiveRecord::Scoping::ScopeRegistry.set_value_for(:current_scope,
56
- # "Board", some_new_scope)
68
+ # Board, some_new_scope)
57
69
  class ScopeRegistry # :nodoc:
58
70
  extend ActiveSupport::PerThreadRegistry
59
71
 
@@ -63,25 +75,31 @@ module ActiveRecord
63
75
  @registry = Hash.new { |hash, key| hash[key] = {} }
64
76
  end
65
77
 
66
- # Obtains the value for a given +scope_name+ and +variable_name+.
67
- def value_for(scope_type, variable_name)
78
+ # Obtains the value for a given +scope_type+ and +model+.
79
+ def value_for(scope_type, model, skip_inherited_scope = false)
68
80
  raise_invalid_scope_type!(scope_type)
69
- @registry[scope_type][variable_name]
81
+ return @registry[scope_type][model.name] if skip_inherited_scope
82
+ klass = model
83
+ base = model.base_class
84
+ while klass <= base
85
+ value = @registry[scope_type][klass.name]
86
+ return value if value
87
+ klass = klass.superclass
88
+ end
70
89
  end
71
90
 
72
- # Sets the +value+ for a given +scope_type+ and +variable_name+.
73
- def set_value_for(scope_type, variable_name, value)
91
+ # Sets the +value+ for a given +scope_type+ and +model+.
92
+ def set_value_for(scope_type, model, value)
74
93
  raise_invalid_scope_type!(scope_type)
75
- @registry[scope_type][variable_name] = value
94
+ @registry[scope_type][model.name] = value
76
95
  end
77
96
 
78
97
  private
79
-
80
- def raise_invalid_scope_type!(scope_type)
81
- if !VALID_SCOPE_TYPES.include?(scope_type)
82
- raise ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry. Scope types must be included in VALID_SCOPE_TYPES"
98
+ def raise_invalid_scope_type!(scope_type)
99
+ if !VALID_SCOPE_TYPES.include?(scope_type)
100
+ raise ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry. Scope types must be included in VALID_SCOPE_TYPES"
101
+ end
83
102
  end
84
- end
85
103
  end
86
104
  end
87
105
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module SecureToken
5
+ class MinimumLengthError < StandardError; end
6
+
7
+ MINIMUM_TOKEN_LENGTH = 24
8
+
9
+ extend ActiveSupport::Concern
10
+
11
+ module ClassMethods
12
+ # Example using #has_secure_token
13
+ #
14
+ # # Schema: User(token:string, auth_token:string)
15
+ # class User < ActiveRecord::Base
16
+ # has_secure_token
17
+ # has_secure_token :auth_token, length: 36
18
+ # end
19
+ #
20
+ # user = User.new
21
+ # user.save
22
+ # user.token # => "pX27zsMN2ViQKta1bGfLmVJE"
23
+ # user.auth_token # => "tU9bLuZseefXQ4yQxQo8wjtBvsAfPc78os6R"
24
+ # user.regenerate_token # => true
25
+ # user.regenerate_auth_token # => true
26
+ #
27
+ # <tt>SecureRandom::base58</tt> is used to generate at minimum a 24-character unique token, so collisions are highly unlikely.
28
+ #
29
+ # Note that it's still possible to generate a race condition in the database in the same way that
30
+ # {validates_uniqueness_of}[rdoc-ref:Validations::ClassMethods#validates_uniqueness_of] can.
31
+ # You're encouraged to add a unique index in the database to deal with this even more unlikely scenario.
32
+ def has_secure_token(attribute = :token, length: MINIMUM_TOKEN_LENGTH)
33
+ if length < MINIMUM_TOKEN_LENGTH
34
+ raise MinimumLengthError, "Token requires a minimum length of #{MINIMUM_TOKEN_LENGTH} characters."
35
+ end
36
+
37
+ # Load securerandom only when has_secure_token is used.
38
+ require "active_support/core_ext/securerandom"
39
+ define_method("regenerate_#{attribute}") { update! attribute => self.class.generate_unique_secure_token(length: length) }
40
+ before_create { send("#{attribute}=", self.class.generate_unique_secure_token(length: length)) unless send("#{attribute}?") }
41
+ end
42
+
43
+ def generate_unique_secure_token(length: MINIMUM_TOKEN_LENGTH)
44
+ SecureRandom.base58(length)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord #:nodoc:
2
- # = Active Record Serialization
4
+ # = Active Record \Serialization
3
5
  module Serialization
4
6
  extend ActiveSupport::Concern
5
7
  include ActiveModel::Serializers::JSON
@@ -9,14 +11,14 @@ module ActiveRecord #:nodoc:
9
11
  end
10
12
 
11
13
  def serializable_hash(options = nil)
12
- options = options.try(:clone) || {}
14
+ if self.class._has_attribute?(self.class.inheritance_column)
15
+ options = options ? options.dup : {}
13
16
 
14
- options[:except] = Array(options[:except]).map { |n| n.to_s }
15
- options[:except] |= Array(self.class.inheritance_column)
17
+ options[:except] = Array(options[:except]).map(&:to_s)
18
+ options[:except] |= Array(self.class.inheritance_column)
19
+ end
16
20
 
17
21
  super(options)
18
22
  end
19
23
  end
20
24
  end
21
-
22
- require 'active_record/serializers/xml_serializer'
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ # = Active Record Signed Id
5
+ module SignedId
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ ##
10
+ # :singleton-method:
11
+ # Set the secret used for the signed id verifier instance when using Active Record outside of Rails.
12
+ # Within Rails, this is automatically set using the Rails application key generator.
13
+ mattr_accessor :signed_id_verifier_secret, instance_writer: false
14
+ end
15
+
16
+ module ClassMethods
17
+ # Lets you find a record based on a signed id that's safe to put into the world without risk of tampering.
18
+ # This is particularly useful for things like password reset or email verification, where you want
19
+ # the bearer of the signed id to be able to interact with the underlying record, but usually only within
20
+ # a certain time period.
21
+ #
22
+ # You set the time period that the signed id is valid for during generation, using the instance method
23
+ # <tt>signed_id(expires_in: 15.minutes)</tt>. If the time has elapsed before a signed find is attempted,
24
+ # the signed id will no longer be valid, and nil is returned.
25
+ #
26
+ # It's possible to further restrict the use of a signed id with a purpose. This helps when you have a
27
+ # general base model, like a User, which might have signed ids for several things, like password reset
28
+ # or email verification. The purpose that was set during generation must match the purpose set when
29
+ # finding. If there's a mismatch, nil is again returned.
30
+ #
31
+ # ==== Examples
32
+ #
33
+ # signed_id = User.first.signed_id expires_in: 15.minutes, purpose: :password_reset
34
+ #
35
+ # User.find_signed signed_id # => nil, since the purpose does not match
36
+ #
37
+ # travel 16.minutes
38
+ # User.find_signed signed_id, purpose: :password_reset # => nil, since the signed id has expired
39
+ #
40
+ # travel_back
41
+ # User.find_signed signed_id, purpose: :password_reset # => User.first
42
+ def find_signed(signed_id, purpose: nil)
43
+ raise UnknownPrimaryKey.new(self) if primary_key.nil?
44
+
45
+ if id = signed_id_verifier.verified(signed_id, purpose: combine_signed_id_purposes(purpose))
46
+ find_by primary_key => id
47
+ end
48
+ end
49
+
50
+ # Works like +find_signed+, but will raise an +ActiveSupport::MessageVerifier::InvalidSignature+
51
+ # exception if the +signed_id+ has either expired, has a purpose mismatch, is for another record,
52
+ # or has been tampered with. It will also raise an +ActiveRecord::RecordNotFound+ exception if
53
+ # the valid signed id can't find a record.
54
+ #
55
+ # === Examples
56
+ #
57
+ # User.find_signed! "bad data" # => ActiveSupport::MessageVerifier::InvalidSignature
58
+ #
59
+ # signed_id = User.first.signed_id
60
+ # User.first.destroy
61
+ # User.find_signed! signed_id # => ActiveRecord::RecordNotFound
62
+ def find_signed!(signed_id, purpose: nil)
63
+ if id = signed_id_verifier.verify(signed_id, purpose: combine_signed_id_purposes(purpose))
64
+ find(id)
65
+ end
66
+ end
67
+
68
+ # The verifier instance that all signed ids are generated and verified from. By default, it'll be initialized
69
+ # with the class-level +signed_id_verifier_secret+, which within Rails comes from the
70
+ # Rails.application.key_generator. By default, it's SHA256 for the digest and JSON for the serialization.
71
+ def signed_id_verifier
72
+ @signed_id_verifier ||= begin
73
+ secret = signed_id_verifier_secret
74
+ secret = secret.call if secret.respond_to?(:call)
75
+
76
+ if secret.nil?
77
+ raise ArgumentError, "You must set ActiveRecord::Base.signed_id_verifier_secret to use signed ids"
78
+ else
79
+ ActiveSupport::MessageVerifier.new secret, digest: "SHA256", serializer: JSON
80
+ end
81
+ end
82
+ end
83
+
84
+ # Allows you to pass in a custom verifier used for the signed ids. This also allows you to use different
85
+ # verifiers for different classes. This is also helpful if you need to rotate keys, as you can prepare
86
+ # your custom verifier for that in advance. See +ActiveSupport::MessageVerifier+ for details.
87
+ def signed_id_verifier=(verifier)
88
+ @signed_id_verifier = verifier
89
+ end
90
+
91
+ # :nodoc:
92
+ def combine_signed_id_purposes(purpose)
93
+ [ base_class.name.underscore, purpose.to_s ].compact_blank.join("/")
94
+ end
95
+ end
96
+
97
+
98
+ # Returns a signed id that's generated using a preconfigured +ActiveSupport::MessageVerifier+ instance.
99
+ # This signed id is tamper proof, so it's safe to send in an email or otherwise share with the outside world.
100
+ # It can further more be set to expire (the default is not to expire), and scoped down with a specific purpose.
101
+ # If the expiration date has been exceeded before +find_signed+ is called, the id won't find the designated
102
+ # record. If a purpose is set, this too must match.
103
+ #
104
+ # If you accidentally let a signed id out in the wild that you wish to retract sooner than its expiration date
105
+ # (or maybe you forgot to set an expiration date while meaning to!), you can use the purpose to essentially
106
+ # version the signed_id, like so:
107
+ #
108
+ # user.signed_id purpose: :v2
109
+ #
110
+ # And you then change your +find_signed+ calls to require this new purpose. Any old signed ids that were not
111
+ # created with the purpose will no longer find the record.
112
+ def signed_id(expires_in: nil, purpose: nil)
113
+ self.class.signed_id_verifier.generate id, expires_in: expires_in, purpose: self.class.combine_signed_id_purposes(purpose)
114
+ end
115
+ end
116
+ end