activerecord 5.0.7.2 → 6.0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (359) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +708 -2040
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +9 -7
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record.rb +37 -22
  8. data/lib/active_record/advisory_lock_base.rb +18 -0
  9. data/lib/active_record/aggregations.rb +249 -247
  10. data/lib/active_record/association_relation.rb +18 -14
  11. data/lib/active_record/associations.rb +1603 -1592
  12. data/lib/active_record/associations/alias_tracker.rb +24 -34
  13. data/lib/active_record/associations/association.rb +114 -55
  14. data/lib/active_record/associations/association_scope.rb +94 -94
  15. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  16. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  17. data/lib/active_record/associations/builder/association.rb +18 -25
  18. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  19. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  20. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +41 -62
  21. data/lib/active_record/associations/builder/has_many.rb +4 -0
  22. data/lib/active_record/associations/builder/has_one.rb +37 -1
  23. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  24. data/lib/active_record/associations/collection_association.rb +86 -254
  25. data/lib/active_record/associations/collection_proxy.rb +158 -122
  26. data/lib/active_record/associations/foreign_association.rb +9 -0
  27. data/lib/active_record/associations/has_many_association.rb +23 -30
  28. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  29. data/lib/active_record/associations/has_one_association.rb +59 -54
  30. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  31. data/lib/active_record/associations/join_dependency.rb +143 -176
  32. data/lib/active_record/associations/join_dependency/join_association.rb +38 -87
  33. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  34. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  35. data/lib/active_record/associations/preloader.rb +90 -103
  36. data/lib/active_record/associations/preloader/association.rb +86 -100
  37. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  38. data/lib/active_record/associations/singular_association.rb +12 -45
  39. data/lib/active_record/associations/through_association.rb +26 -14
  40. data/lib/active_record/attribute_assignment.rb +54 -61
  41. data/lib/active_record/attribute_decorators.rb +38 -17
  42. data/lib/active_record/attribute_methods.rb +66 -106
  43. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
  44. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  45. data/lib/active_record/attribute_methods/primary_key.rb +85 -92
  46. data/lib/active_record/attribute_methods/query.rb +4 -3
  47. data/lib/active_record/attribute_methods/read.rb +20 -49
  48. data/lib/active_record/attribute_methods/serialization.rb +29 -7
  49. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
  50. data/lib/active_record/attribute_methods/write.rb +34 -33
  51. data/lib/active_record/attributes.rb +38 -25
  52. data/lib/active_record/autosave_association.rb +54 -35
  53. data/lib/active_record/base.rb +27 -24
  54. data/lib/active_record/callbacks.rb +64 -35
  55. data/lib/active_record/coders/json.rb +2 -0
  56. data/lib/active_record/coders/yaml_column.rb +11 -12
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +552 -323
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +228 -147
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +367 -202
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +396 -562
  70. data/lib/active_record/connection_adapters/column.rb +41 -13
  71. data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  73. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +137 -49
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  80. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  81. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  82. data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -54
  85. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  87. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  97. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  99. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  101. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -31
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  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 +8 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  109. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  110. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +20 -26
  111. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  113. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +378 -308
  115. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  116. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  117. data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -275
  118. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  119. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  120. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  121. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  122. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  123. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  124. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  127. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +259 -266
  128. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  129. data/lib/active_record/connection_handling.rb +143 -40
  130. data/lib/active_record/core.rb +201 -163
  131. data/lib/active_record/counter_cache.rb +60 -28
  132. data/lib/active_record/database_configurations.rb +233 -0
  133. data/lib/active_record/database_configurations/database_config.rb +37 -0
  134. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  135. data/lib/active_record/database_configurations/url_config.rb +78 -0
  136. data/lib/active_record/define_callbacks.rb +22 -0
  137. data/lib/active_record/dynamic_matchers.rb +87 -87
  138. data/lib/active_record/enum.rb +60 -23
  139. data/lib/active_record/errors.rb +114 -18
  140. data/lib/active_record/explain.rb +4 -4
  141. data/lib/active_record/explain_registry.rb +3 -1
  142. data/lib/active_record/explain_subscriber.rb +9 -4
  143. data/lib/active_record/fixture_set/file.rb +13 -8
  144. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  145. data/lib/active_record/fixture_set/render_context.rb +17 -0
  146. data/lib/active_record/fixture_set/table_row.rb +152 -0
  147. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  148. data/lib/active_record/fixtures.rb +194 -504
  149. data/lib/active_record/gem_version.rb +5 -3
  150. data/lib/active_record/inheritance.rb +150 -99
  151. data/lib/active_record/insert_all.rb +179 -0
  152. data/lib/active_record/integration.rb +116 -25
  153. data/lib/active_record/internal_metadata.rb +16 -19
  154. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  155. data/lib/active_record/locking/optimistic.rb +77 -87
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +48 -29
  158. data/lib/active_record/middleware/database_selector.rb +74 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  160. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  161. data/lib/active_record/migration.rb +369 -302
  162. data/lib/active_record/migration/command_recorder.rb +134 -100
  163. data/lib/active_record/migration/compatibility.rb +174 -56
  164. data/lib/active_record/migration/join_table.rb +8 -7
  165. data/lib/active_record/model_schema.rb +131 -127
  166. data/lib/active_record/nested_attributes.rb +213 -202
  167. data/lib/active_record/no_touching.rb +12 -3
  168. data/lib/active_record/null_relation.rb +12 -34
  169. data/lib/active_record/persistence.rb +446 -77
  170. data/lib/active_record/query_cache.rb +13 -12
  171. data/lib/active_record/querying.rb +37 -24
  172. data/lib/active_record/railtie.rb +128 -36
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +2 -0
  175. data/lib/active_record/railties/controller_runtime.rb +34 -33
  176. data/lib/active_record/railties/databases.rake +312 -177
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +214 -252
  179. data/lib/active_record/relation.rb +440 -318
  180. data/lib/active_record/relation/batches.rb +98 -52
  181. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  182. data/lib/active_record/relation/calculations.rb +212 -173
  183. data/lib/active_record/relation/delegation.rb +72 -69
  184. data/lib/active_record/relation/finder_methods.rb +207 -247
  185. data/lib/active_record/relation/from_clause.rb +6 -8
  186. data/lib/active_record/relation/merger.rb +78 -62
  187. data/lib/active_record/relation/predicate_builder.rb +83 -105
  188. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  189. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  190. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  191. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  192. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  193. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  194. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  195. data/lib/active_record/relation/query_attribute.rb +33 -2
  196. data/lib/active_record/relation/query_methods.rb +476 -334
  197. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  198. data/lib/active_record/relation/spawn_methods.rb +8 -8
  199. data/lib/active_record/relation/where_clause.rb +111 -96
  200. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  201. data/lib/active_record/result.rb +69 -40
  202. data/lib/active_record/runtime_registry.rb +5 -3
  203. data/lib/active_record/sanitization.rb +83 -99
  204. data/lib/active_record/schema.rb +7 -14
  205. data/lib/active_record/schema_dumper.rb +71 -69
  206. data/lib/active_record/schema_migration.rb +16 -6
  207. data/lib/active_record/scoping.rb +20 -20
  208. data/lib/active_record/scoping/default.rb +92 -95
  209. data/lib/active_record/scoping/named.rb +47 -27
  210. data/lib/active_record/secure_token.rb +4 -2
  211. data/lib/active_record/serialization.rb +2 -0
  212. data/lib/active_record/statement_cache.rb +63 -28
  213. data/lib/active_record/store.rb +121 -41
  214. data/lib/active_record/suppressor.rb +6 -3
  215. data/lib/active_record/table_metadata.rb +39 -18
  216. data/lib/active_record/tasks/database_tasks.rb +271 -81
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +225 -0
  222. data/lib/active_record/timestamp.rb +70 -36
  223. data/lib/active_record/touch_later.rb +8 -6
  224. data/lib/active_record/transactions.rb +141 -157
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type.rb +23 -18
  227. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  228. data/lib/active_record/type/date.rb +2 -0
  229. data/lib/active_record/type/date_time.rb +2 -0
  230. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  231. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  232. data/lib/active_record/type/internal/timezone.rb +2 -0
  233. data/lib/active_record/type/json.rb +30 -0
  234. data/lib/active_record/type/serialized.rb +16 -9
  235. data/lib/active_record/type/text.rb +11 -0
  236. data/lib/active_record/type/time.rb +2 -1
  237. data/lib/active_record/type/type_map.rb +14 -17
  238. data/lib/active_record/type/unsigned_integer.rb +16 -0
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/type_caster/connection.rb +17 -12
  241. data/lib/active_record/type_caster/map.rb +5 -4
  242. data/lib/active_record/validations.rb +7 -5
  243. data/lib/active_record/validations/absence.rb +2 -0
  244. data/lib/active_record/validations/associated.rb +4 -3
  245. data/lib/active_record/validations/length.rb +2 -0
  246. data/lib/active_record/validations/presence.rb +4 -2
  247. data/lib/active_record/validations/uniqueness.rb +29 -42
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/arel.rb +62 -0
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/attributes/attribute.rb +37 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes.rb +68 -0
  266. data/lib/arel/nodes/and.rb +32 -0
  267. data/lib/arel/nodes/ascending.rb +23 -0
  268. data/lib/arel/nodes/binary.rb +52 -0
  269. data/lib/arel/nodes/bind_param.rb +36 -0
  270. data/lib/arel/nodes/case.rb +55 -0
  271. data/lib/arel/nodes/casted.rb +50 -0
  272. data/lib/arel/nodes/comment.rb +29 -0
  273. data/lib/arel/nodes/count.rb +12 -0
  274. data/lib/arel/nodes/delete_statement.rb +45 -0
  275. data/lib/arel/nodes/descending.rb +23 -0
  276. data/lib/arel/nodes/equality.rb +18 -0
  277. data/lib/arel/nodes/extract.rb +24 -0
  278. data/lib/arel/nodes/false.rb +16 -0
  279. data/lib/arel/nodes/full_outer_join.rb +8 -0
  280. data/lib/arel/nodes/function.rb +44 -0
  281. data/lib/arel/nodes/grouping.rb +8 -0
  282. data/lib/arel/nodes/in.rb +8 -0
  283. data/lib/arel/nodes/infix_operation.rb +80 -0
  284. data/lib/arel/nodes/inner_join.rb +8 -0
  285. data/lib/arel/nodes/insert_statement.rb +37 -0
  286. data/lib/arel/nodes/join_source.rb +20 -0
  287. data/lib/arel/nodes/matches.rb +18 -0
  288. data/lib/arel/nodes/named_function.rb +23 -0
  289. data/lib/arel/nodes/node.rb +50 -0
  290. data/lib/arel/nodes/node_expression.rb +13 -0
  291. data/lib/arel/nodes/outer_join.rb +8 -0
  292. data/lib/arel/nodes/over.rb +15 -0
  293. data/lib/arel/nodes/regexp.rb +16 -0
  294. data/lib/arel/nodes/right_outer_join.rb +8 -0
  295. data/lib/arel/nodes/select_core.rb +67 -0
  296. data/lib/arel/nodes/select_statement.rb +41 -0
  297. data/lib/arel/nodes/sql_literal.rb +16 -0
  298. data/lib/arel/nodes/string_join.rb +11 -0
  299. data/lib/arel/nodes/table_alias.rb +27 -0
  300. data/lib/arel/nodes/terminal.rb +16 -0
  301. data/lib/arel/nodes/true.rb +16 -0
  302. data/lib/arel/nodes/unary.rb +45 -0
  303. data/lib/arel/nodes/unary_operation.rb +20 -0
  304. data/lib/arel/nodes/unqualified_column.rb +22 -0
  305. data/lib/arel/nodes/update_statement.rb +41 -0
  306. data/lib/arel/nodes/values_list.rb +9 -0
  307. data/lib/arel/nodes/window.rb +126 -0
  308. data/lib/arel/nodes/with.rb +11 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +256 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors.rb +20 -0
  316. data/lib/arel/visitors/depth_first.rb +203 -0
  317. data/lib/arel/visitors/dot.rb +296 -0
  318. data/lib/arel/visitors/ibm_db.rb +34 -0
  319. data/lib/arel/visitors/informix.rb +62 -0
  320. data/lib/arel/visitors/mssql.rb +156 -0
  321. data/lib/arel/visitors/mysql.rb +83 -0
  322. data/lib/arel/visitors/oracle.rb +158 -0
  323. data/lib/arel/visitors/oracle12.rb +65 -0
  324. data/lib/arel/visitors/postgresql.rb +109 -0
  325. data/lib/arel/visitors/sqlite.rb +38 -0
  326. data/lib/arel/visitors/to_sql.rb +888 -0
  327. data/lib/arel/visitors/visitor.rb +45 -0
  328. data/lib/arel/visitors/where_sql.rb +22 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/rails/generators/active_record.rb +7 -5
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  332. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  333. data/lib/rails/generators/active_record/migration.rb +17 -3
  334. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  335. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  336. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  337. data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
  338. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  339. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  340. metadata +137 -52
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  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 -15
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  350. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/attribute_set/builder.rb +0 -132
  353. data/lib/active_record/collection_cache_key.rb +0 -50
  354. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  355. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  356. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  357. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  358. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  359. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,11 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
- # = Active Record Through Association
3
4
  module Associations
5
+ # = Active Record Through Association
4
6
  module ThroughAssociation #:nodoc:
7
+ delegate :source_reflection, to: :reflection
8
+
9
+ private
10
+ def through_reflection
11
+ @through_reflection ||= begin
12
+ refl = reflection.through_reflection
5
13
 
6
- delegate :source_reflection, :through_reflection, :to => :reflection
14
+ while refl.through_reflection?
15
+ refl = refl.through_reflection
16
+ end
7
17
 
8
- protected
18
+ refl
19
+ end
20
+ end
21
+
22
+ def through_association
23
+ @through_association ||= owner.association(through_reflection.name)
24
+ end
9
25
 
10
26
  # We merge in these scopes for two reasons:
11
27
  #
@@ -22,8 +38,6 @@ module ActiveRecord
22
38
  scope
23
39
  end
24
40
 
25
- private
26
-
27
41
  # Construct attributes for :through pointing to owner and associate. This is used by the
28
42
  # methods which create and delete records on the association.
29
43
  #
@@ -39,24 +53,22 @@ module ActiveRecord
39
53
  def construct_join_attributes(*records)
40
54
  ensure_mutable
41
55
 
42
- if source_reflection.association_primary_key(reflection.klass) == reflection.klass.primary_key
56
+ association_primary_key = source_reflection.association_primary_key(reflection.klass)
57
+
58
+ if association_primary_key == reflection.klass.primary_key && !options[:source_type]
43
59
  join_attributes = { source_reflection.name => records }
44
60
  else
45
61
  join_attributes = {
46
- source_reflection.foreign_key =>
47
- records.map { |record|
48
- record.send(source_reflection.association_primary_key(reflection.klass))
49
- }
62
+ source_reflection.foreign_key => records.map(&association_primary_key.to_sym)
50
63
  }
51
64
  end
52
65
 
53
66
  if options[:source_type]
54
- join_attributes[source_reflection.foreign_type] =
55
- records.map { |record| record.class.base_class.name }
67
+ join_attributes[source_reflection.foreign_type] = [ options[:source_type] ]
56
68
  end
57
69
 
58
70
  if records.count == 1
59
- Hash[join_attributes.map { |k, v| [k, v.first] }]
71
+ join_attributes.transform_values!(&:first)
60
72
  else
61
73
  join_attributes
62
74
  end
@@ -102,7 +114,7 @@ module ActiveRecord
102
114
  attributes[inverse.foreign_key] = target.id
103
115
  end
104
116
 
105
- super(attributes)
117
+ super
106
118
  end
107
119
  end
108
120
  end
@@ -1,55 +1,49 @@
1
- require 'active_model/forbidden_attributes_protection'
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
7
  include ActiveModel::AttributeAssignment
7
8
 
8
- # Alias for ActiveModel::AttributeAssignment#assign_attributes. See ActiveModel::AttributeAssignment.
9
- def attributes=(attributes)
10
- assign_attributes(attributes)
11
- end
12
-
13
9
  private
10
+ def _assign_attributes(attributes)
11
+ multi_parameter_attributes = {}
12
+ nested_parameter_attributes = {}
14
13
 
15
- def _assign_attributes(attributes) # :nodoc:
16
- multi_parameter_attributes = {}
17
- nested_parameter_attributes = {}
18
-
19
- attributes.each do |k, v|
20
- if k.include?("(")
21
- multi_parameter_attributes[k] = attributes.delete(k)
22
- elsif v.is_a?(Hash)
23
- nested_parameter_attributes[k] = attributes.delete(k)
14
+ attributes.each do |k, v|
15
+ if k.include?("(")
16
+ multi_parameter_attributes[k] = attributes.delete(k)
17
+ elsif v.is_a?(Hash)
18
+ nested_parameter_attributes[k] = attributes.delete(k)
19
+ end
24
20
  end
25
- end
26
- super(attributes)
21
+ super(attributes)
27
22
 
28
- assign_nested_parameter_attributes(nested_parameter_attributes) unless nested_parameter_attributes.empty?
29
- assign_multiparameter_attributes(multi_parameter_attributes) unless multi_parameter_attributes.empty?
30
- end
23
+ assign_nested_parameter_attributes(nested_parameter_attributes) unless nested_parameter_attributes.empty?
24
+ assign_multiparameter_attributes(multi_parameter_attributes) unless multi_parameter_attributes.empty?
25
+ end
31
26
 
32
- # Assign any deferred nested attributes after the base attributes have been set.
33
- def assign_nested_parameter_attributes(pairs)
34
- pairs.each { |k, v| _assign_attribute(k, v) }
35
- end
27
+ # Assign any deferred nested attributes after the base attributes have been set.
28
+ def assign_nested_parameter_attributes(pairs)
29
+ pairs.each { |k, v| _assign_attribute(k, v) }
30
+ end
36
31
 
37
- # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
38
- # by calling new on the column type or aggregation type (through composed_of) object with these parameters.
39
- # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
40
- # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
41
- # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Integer and
42
- # f for Float. If all the values for a given attribute are empty, the attribute will be set to +nil+.
43
- def assign_multiparameter_attributes(pairs)
44
- execute_callstack_for_multiparameter_attributes(
45
- extract_callstack_for_multiparameter_attributes(pairs)
46
- )
47
- end
32
+ # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
33
+ # by calling new on the column type or aggregation type (through composed_of) object with these parameters.
34
+ # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
35
+ # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
36
+ # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Integer and
37
+ # f for Float. If all the values for a given attribute are empty, the attribute will be set to +nil+.
38
+ def assign_multiparameter_attributes(pairs)
39
+ execute_callstack_for_multiparameter_attributes(
40
+ extract_callstack_for_multiparameter_attributes(pairs)
41
+ )
42
+ end
48
43
 
49
- def execute_callstack_for_multiparameter_attributes(callstack)
50
- errors = []
51
- callstack.each do |name, values_with_empty_parameters|
52
- begin
44
+ def execute_callstack_for_multiparameter_attributes(callstack)
45
+ errors = []
46
+ callstack.each do |name, values_with_empty_parameters|
53
47
  if values_with_empty_parameters.each_value.all?(&:nil?)
54
48
  values = nil
55
49
  else
@@ -59,33 +53,32 @@ module ActiveRecord
59
53
  rescue => ex
60
54
  errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name} (#{ex.message})", ex, name)
61
55
  end
56
+ unless errors.empty?
57
+ error_descriptions = errors.map(&:message).join(",")
58
+ raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]"
59
+ end
62
60
  end
63
- unless errors.empty?
64
- error_descriptions = errors.map(&:message).join(",")
65
- raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]"
66
- end
67
- end
68
61
 
69
- def extract_callstack_for_multiparameter_attributes(pairs)
70
- attributes = {}
62
+ def extract_callstack_for_multiparameter_attributes(pairs)
63
+ attributes = {}
71
64
 
72
- pairs.each do |(multiparameter_name, value)|
73
- attribute_name = multiparameter_name.split("(").first
74
- attributes[attribute_name] ||= {}
65
+ pairs.each do |(multiparameter_name, value)|
66
+ attribute_name = multiparameter_name.split("(").first
67
+ attributes[attribute_name] ||= {}
75
68
 
76
- parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
77
- attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
78
- end
69
+ parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
70
+ attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
71
+ end
79
72
 
80
- attributes
81
- end
73
+ attributes
74
+ end
82
75
 
83
- def type_cast_attribute_value(multiparameter_name, value)
84
- multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
85
- end
76
+ def type_cast_attribute_value(multiparameter_name, value)
77
+ multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
78
+ end
86
79
 
87
- def find_parameter_position(multiparameter_name)
88
- multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
89
- end
80
+ def find_parameter_position(multiparameter_name)
81
+ multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
82
+ end
90
83
  end
91
84
  end
@@ -1,19 +1,42 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module AttributeDecorators # :nodoc:
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  included do
6
- class_attribute :attribute_type_decorations, instance_accessor: false # :internal:
7
- self.attribute_type_decorations = TypeDecorator.new
8
+ class_attribute :attribute_type_decorations, instance_accessor: false, default: TypeDecorator.new # :internal:
8
9
  end
9
10
 
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+
11
23
  def decorate_attribute_type(column_name, decorator_name, &block)
12
24
  matcher = ->(name, _) { name == column_name.to_s }
13
25
  key = "_#{column_name}_#{decorator_name}"
14
26
  decorate_matching_attribute_types(matcher, key, &block)
15
27
  end
16
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.
17
40
  def decorate_matching_attribute_types(matcher, decorator_name, &block)
18
41
  reload_schema_from_cache
19
42
  decorator_name = decorator_name.to_s
@@ -23,14 +46,13 @@ module ActiveRecord
23
46
  end
24
47
 
25
48
  private
26
-
27
- def load_schema!
28
- super
29
- attribute_types.each do |name, type|
30
- decorated_type = attribute_type_decorations.apply(name, type)
31
- define_attribute(name, decorated_type)
49
+ def load_schema!
50
+ super
51
+ attribute_types.each do |name, type|
52
+ decorated_type = attribute_type_decorations.apply(name, type)
53
+ define_attribute(name, decorated_type)
54
+ end
32
55
  end
33
- end
34
56
  end
35
57
 
36
58
  class TypeDecorator # :nodoc:
@@ -52,16 +74,15 @@ module ActiveRecord
52
74
  end
53
75
 
54
76
  private
77
+ def decorators_for(name, type)
78
+ matching(name, type).map(&:last)
79
+ end
55
80
 
56
- def decorators_for(name, type)
57
- matching(name, type).map(&:last)
58
- end
59
-
60
- def matching(name, type)
61
- @decorations.values.select do |(matcher, _)|
62
- matcher.call(name, type)
81
+ def matching(name, type)
82
+ @decorations.values.select do |(matcher, _)|
83
+ matcher.call(name, type)
84
+ end
63
85
  end
64
- end
65
86
  end
66
87
  end
67
88
  end
@@ -1,7 +1,6 @@
1
- require 'active_support/core_ext/enumerable'
2
- require 'active_support/core_ext/string/filters'
3
- require 'mutex_m'
4
- require 'concurrent/map'
1
+ # frozen_string_literal: true
2
+
3
+ require "mutex_m"
5
4
 
6
5
  module ActiveRecord
7
6
  # = Active Record Attribute Methods
@@ -23,18 +22,11 @@ module ActiveRecord
23
22
  delegate :column_for_attribute, to: :class
24
23
  end
25
24
 
26
- AttrNames = Module.new {
27
- def self.set_name_cache(name, value)
28
- const_name = "ATTR_#{name}"
29
- unless const_defined? const_name
30
- const_set const_name, value.dup.freeze
31
- end
32
- end
33
- }
25
+ RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
34
26
 
35
- BLACKLISTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
36
-
37
- class GeneratedAttributeMethods < Module; end # :nodoc:
27
+ class GeneratedAttributeMethods < Module #:nodoc:
28
+ include Mutex_m
29
+ end
38
30
 
39
31
  module ClassMethods
40
32
  def inherited(child_class) #:nodoc:
@@ -43,7 +35,8 @@ module ActiveRecord
43
35
  end
44
36
 
45
37
  def initialize_generated_modules # :nodoc:
46
- @generated_attribute_methods = GeneratedAttributeMethods.new { extend Mutex_m }
38
+ @generated_attribute_methods = const_set(:GeneratedAttributeMethods, GeneratedAttributeMethods.new)
39
+ private_constant :GeneratedAttributeMethods
47
40
  @attribute_methods_generated = false
48
41
  include @generated_attribute_methods
49
42
 
@@ -58,11 +51,10 @@ module ActiveRecord
58
51
  # attribute methods.
59
52
  generated_attribute_methods.synchronize do
60
53
  return false if @attribute_methods_generated
61
- superclass.define_attribute_methods unless self == base_class
54
+ superclass.define_attribute_methods unless base_class?
62
55
  super(attribute_names)
63
56
  @attribute_methods_generated = true
64
57
  end
65
- true
66
58
  end
67
59
 
68
60
  def undefine_attribute_methods # :nodoc:
@@ -123,7 +115,7 @@ module ActiveRecord
123
115
  # A class method is 'dangerous' if it is already (re)defined by Active Record, but
124
116
  # not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
125
117
  def dangerous_class_method?(method_name)
126
- BLACKLISTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
118
+ RESTRICTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
127
119
  end
128
120
 
129
121
  def class_method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
@@ -148,7 +140,7 @@ module ActiveRecord
148
140
  # Person.attribute_method?(:age=) # => true
149
141
  # Person.attribute_method?(:nothing) # => false
150
142
  def attribute_method?(attribute)
151
- super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, '')))
143
+ super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, "")))
152
144
  end
153
145
 
154
146
  # Returns an array of column names as strings if it's not an abstract class and
@@ -161,10 +153,10 @@ module ActiveRecord
161
153
  # # => ["id", "created_at", "updated_at", "name", "age"]
162
154
  def attribute_names
163
155
  @attribute_names ||= if !abstract_class? && table_exists?
164
- attribute_types.keys
165
- else
166
- []
167
- end
156
+ attribute_types.keys
157
+ else
158
+ []
159
+ end
168
160
  end
169
161
 
170
162
  # Returns true if the given attribute exists, otherwise false.
@@ -209,34 +201,27 @@ module ActiveRecord
209
201
  # end
210
202
  #
211
203
  # person = Person.new
212
- # person.respond_to(:name) # => true
213
- # person.respond_to(:name=) # => true
214
- # person.respond_to(:name?) # => true
215
- # person.respond_to('age') # => true
216
- # person.respond_to('age=') # => true
217
- # person.respond_to('age?') # => true
218
- # person.respond_to(:nothing) # => false
204
+ # person.respond_to?(:name) # => true
205
+ # person.respond_to?(:name=) # => true
206
+ # person.respond_to?(:name?) # => true
207
+ # person.respond_to?('age') # => true
208
+ # person.respond_to?('age=') # => true
209
+ # person.respond_to?('age?') # => true
210
+ # person.respond_to?(:nothing) # => false
219
211
  def respond_to?(name, include_private = false)
220
212
  return false unless super
221
213
 
222
- case name
223
- when :to_partial_path
224
- name = "to_partial_path".freeze
225
- when :to_model
226
- name = "to_model".freeze
227
- else
228
- name = name.to_s
229
- end
230
-
231
214
  # If the result is true then check for the select case.
232
215
  # For queries selecting a subset of columns, return false for unselected columns.
233
216
  # We check defined?(@attributes) not to issue warnings if called on objects that
234
217
  # have been allocated but not yet initialized.
235
- if defined?(@attributes) && self.class.column_names.include?(name)
236
- return has_attribute?(name)
218
+ if defined?(@attributes)
219
+ if name = self.class.symbol_column_to_string(name.to_sym)
220
+ return has_attribute?(name)
221
+ end
237
222
  end
238
223
 
239
- return true
224
+ true
240
225
  end
241
226
 
242
227
  # Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
@@ -293,15 +278,8 @@ module ActiveRecord
293
278
  # person.attribute_for_inspect(:tag_ids)
294
279
  # # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
295
280
  def attribute_for_inspect(attr_name)
296
- value = read_attribute(attr_name)
297
-
298
- if value.is_a?(String) && value.length > 50
299
- "#{value[0, 50]}...".inspect
300
- elsif value.is_a?(Date) || value.is_a?(Time)
301
- %("#{value.to_s(:db)}")
302
- else
303
- value.inspect
304
- end
281
+ value = _read_attribute(attr_name)
282
+ format_for_inspect(value)
305
283
  end
306
284
 
307
285
  # Returns +true+ if the specified +attribute+ has been set by the user or by a
@@ -330,8 +308,6 @@ module ActiveRecord
330
308
  #
331
309
  # Note: +:id+ is always present.
332
310
  #
333
- # Alias for the #read_attribute method.
334
- #
335
311
  # class Person < ActiveRecord::Base
336
312
  # belongs_to :organization
337
313
  # end
@@ -394,67 +370,51 @@ module ActiveRecord
394
370
  @attributes.accessed
395
371
  end
396
372
 
397
- protected
398
-
399
- def clone_attribute_value(reader_method, attribute_name) # :nodoc:
400
- value = send(reader_method, attribute_name)
401
- value.duplicable? ? value.clone : value
402
- rescue TypeError, NoMethodError
403
- value
404
- end
405
-
406
- def arel_attributes_with_values_for_create(attribute_names) # :nodoc:
407
- arel_attributes_with_values(attributes_for_create(attribute_names))
408
- end
409
-
410
- def arel_attributes_with_values_for_update(attribute_names) # :nodoc:
411
- arel_attributes_with_values(attributes_for_update(attribute_names))
412
- end
413
-
414
- def attribute_method?(attr_name) # :nodoc:
415
- # We check defined? because Syck calls respond_to? before actually calling initialize.
416
- defined?(@attributes) && @attributes.key?(attr_name)
417
- end
418
-
419
373
  private
374
+ def attribute_method?(attr_name)
375
+ # We check defined? because Syck calls respond_to? before actually calling initialize.
376
+ defined?(@attributes) && @attributes.key?(attr_name)
377
+ end
420
378
 
421
- # Returns a Hash of the Arel::Attributes and attribute values that have been
422
- # typecasted for use in an Arel insert/update method.
423
- def arel_attributes_with_values(attribute_names)
424
- attrs = {}
425
- arel_table = self.class.arel_table
426
-
427
- attribute_names.each do |name|
428
- attrs[arel_table[name]] = typecasted_attribute_value(name)
379
+ def attributes_with_values(attribute_names)
380
+ attribute_names.each_with_object({}) do |name, attrs|
381
+ attrs[name] = _read_attribute(name)
382
+ end
429
383
  end
430
- attrs
431
- end
432
384
 
433
- # Filters the primary keys and readonly attributes from the attribute names.
434
- def attributes_for_update(attribute_names)
435
- attribute_names.reject do |name|
436
- readonly_attribute?(name)
385
+ # Filters the primary keys and readonly attributes from the attribute names.
386
+ def attributes_for_update(attribute_names)
387
+ attribute_names &= self.class.column_names
388
+ attribute_names.delete_if do |name|
389
+ readonly_attribute?(name)
390
+ end
437
391
  end
438
- end
439
392
 
440
- # Filters out the primary keys, from the attribute names, when the primary
441
- # key is to be generated (e.g. the id attribute has no value).
442
- def attributes_for_create(attribute_names)
443
- attribute_names.reject do |name|
444
- pk_attribute?(name) && id.nil?
393
+ # Filters out the primary keys, from the attribute names, when the primary
394
+ # key is to be generated (e.g. the id attribute has no value).
395
+ def attributes_for_create(attribute_names)
396
+ attribute_names &= self.class.column_names
397
+ attribute_names.delete_if do |name|
398
+ pk_attribute?(name) && id.nil?
399
+ end
445
400
  end
446
- end
447
401
 
448
- def readonly_attribute?(name)
449
- self.class.readonly_attributes.include?(name)
450
- end
402
+ def format_for_inspect(value)
403
+ if value.is_a?(String) && value.length > 50
404
+ "#{value[0, 50]}...".inspect
405
+ elsif value.is_a?(Date) || value.is_a?(Time)
406
+ %("#{value.to_s(:db)}")
407
+ else
408
+ value.inspect
409
+ end
410
+ end
451
411
 
452
- def pk_attribute?(name)
453
- name == self.class.primary_key
454
- end
412
+ def readonly_attribute?(name)
413
+ self.class.readonly_attributes.include?(name)
414
+ end
455
415
 
456
- def typecasted_attribute_value(name)
457
- _read_attribute(name)
458
- end
416
+ def pk_attribute?(name)
417
+ name == @primary_key
418
+ end
459
419
  end
460
420
  end