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,13 +1,15 @@
1
- require 'active_support/core_ext/enumerable'
2
- require 'active_support/deprecation'
1
+ # frozen_string_literal: true
2
+
3
+ require "mutex_m"
3
4
 
4
5
  module ActiveRecord
5
6
  # = Active Record Attribute Methods
6
- module AttributeMethods #:nodoc:
7
+ module AttributeMethods
7
8
  extend ActiveSupport::Concern
8
9
  include ActiveModel::AttributeMethods
9
10
 
10
11
  included do
12
+ initialize_generated_modules
11
13
  include Read
12
14
  include Write
13
15
  include BeforeTypeCast
@@ -16,100 +18,92 @@ module ActiveRecord
16
18
  include TimeZoneConversion
17
19
  include Dirty
18
20
  include Serialization
19
- include DeprecatedUnderscoreRead
20
21
 
21
- # Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
22
- # "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
23
- # (Alias for the protected read_attribute method).
24
- def [](attr_name)
25
- read_attribute(attr_name)
26
- end
22
+ delegate :column_for_attribute, to: :class
23
+ end
27
24
 
28
- # Updates the attribute identified by <tt>attr_name</tt> with the specified +value+.
29
- # (Alias for the protected write_attribute method).
30
- def []=(attr_name, value)
31
- write_attribute(attr_name, value)
32
- end
25
+ RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
26
+
27
+ class GeneratedAttributeMethods < Module #:nodoc:
28
+ include Mutex_m
33
29
  end
34
30
 
35
31
  module ClassMethods
36
- # Generates all the attribute related methods for columns in the database
37
- # accessors, mutators and query methods.
38
- def define_attribute_methods
39
- unless defined?(@attribute_methods_mutex)
40
- msg = "It looks like something (probably a gem/plugin) is overriding the " \
41
- "ActiveRecord::Base.inherited method. It is important that this hook executes so " \
42
- "that your models are set up correctly. A workaround has been added to stop this " \
43
- "causing an error in 3.2, but future versions will simply not work if the hook is " \
44
- "overridden. If you are using Kaminari, please upgrade as it is known to have had " \
45
- "this problem.\n\n"
46
- msg << "The following may help track down the problem:"
47
-
48
- meth = method(:inherited)
49
- if meth.respond_to?(:source_location)
50
- msg << " #{meth.source_location.inspect}"
51
- else
52
- msg << " #{meth.inspect}"
53
- end
54
- msg << "\n\n"
32
+ def inherited(child_class) #:nodoc:
33
+ child_class.initialize_generated_modules
34
+ super
35
+ end
55
36
 
56
- ActiveSupport::Deprecation.warn(msg)
37
+ def initialize_generated_modules # :nodoc:
38
+ @generated_attribute_methods = const_set(:GeneratedAttributeMethods, GeneratedAttributeMethods.new)
39
+ private_constant :GeneratedAttributeMethods
40
+ @attribute_methods_generated = false
41
+ include @generated_attribute_methods
57
42
 
58
- @attribute_methods_mutex = Mutex.new
59
- end
43
+ super
44
+ end
60
45
 
61
- # Use a mutex; we don't want two thread simaltaneously trying to define
46
+ # Generates all the attribute related methods for columns in the database
47
+ # accessors, mutators and query methods.
48
+ def define_attribute_methods # :nodoc:
49
+ return false if @attribute_methods_generated
50
+ # Use a mutex; we don't want two threads simultaneously trying to define
62
51
  # attribute methods.
63
- @attribute_methods_mutex.synchronize do
64
- return if attribute_methods_generated?
65
- superclass.define_attribute_methods unless self == base_class
66
- super(column_names)
67
- column_names.each { |name| define_external_attribute_method(name) }
52
+ generated_attribute_methods.synchronize do
53
+ return false if @attribute_methods_generated
54
+ superclass.define_attribute_methods unless base_class?
55
+ super(attribute_names)
68
56
  @attribute_methods_generated = true
69
57
  end
70
58
  end
71
59
 
72
- def attribute_methods_generated?
73
- @attribute_methods_generated ||= false
74
- end
75
-
76
- # We will define the methods as instance methods, but will call them as singleton
77
- # methods. This allows us to use method_defined? to check if the method exists,
78
- # which is fast and won't give any false positives from the ancestors (because
79
- # there are no ancestors).
80
- def generated_external_attribute_methods
81
- @generated_external_attribute_methods ||= Module.new { extend self }
82
- end
83
-
84
- def undefine_attribute_methods
85
- super
86
- @attribute_methods_generated = false
60
+ def undefine_attribute_methods # :nodoc:
61
+ generated_attribute_methods.synchronize do
62
+ super if defined?(@attribute_methods_generated) && @attribute_methods_generated
63
+ @attribute_methods_generated = false
64
+ end
87
65
  end
88
66
 
67
+ # Raises an ActiveRecord::DangerousAttributeError exception when an
68
+ # \Active \Record method is defined in the model, otherwise +false+.
69
+ #
70
+ # class Person < ActiveRecord::Base
71
+ # def save
72
+ # 'already defined by Active Record'
73
+ # end
74
+ # end
75
+ #
76
+ # Person.instance_method_already_implemented?(:save)
77
+ # # => ActiveRecord::DangerousAttributeError: save is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name.
78
+ #
79
+ # Person.instance_method_already_implemented?(:name)
80
+ # # => false
89
81
  def instance_method_already_implemented?(method_name)
90
82
  if dangerous_attribute_method?(method_name)
91
- raise DangerousAttributeError, "#{method_name} is defined by ActiveRecord"
83
+ raise DangerousAttributeError, "#{method_name} is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name."
92
84
  end
93
85
 
94
86
  if superclass == Base
95
87
  super
96
88
  else
97
- # If B < A and A defines its own attribute method, then we don't want to overwrite that.
98
- defined = method_defined_within?(method_name, superclass, superclass.generated_attribute_methods)
99
- defined && !ActiveRecord::Base.method_defined?(method_name) || super
89
+ # If ThisClass < ... < SomeSuperClass < ... < Base and SomeSuperClass
90
+ # defines its own attribute method, then we don't want to overwrite that.
91
+ defined = method_defined_within?(method_name, superclass, Base) &&
92
+ ! superclass.instance_method(method_name).owner.is_a?(GeneratedAttributeMethods)
93
+ defined || super
100
94
  end
101
95
  end
102
96
 
103
- # A method name is 'dangerous' if it is already defined by Active Record, but
97
+ # A method name is 'dangerous' if it is already (re)defined by Active Record, but
104
98
  # not by any ancestors. (So 'puts' is not dangerous but 'save' is.)
105
- def dangerous_attribute_method?(name)
99
+ def dangerous_attribute_method?(name) # :nodoc:
106
100
  method_defined_within?(name, Base)
107
101
  end
108
102
 
109
- def method_defined_within?(name, klass, sup = klass.superclass)
103
+ def method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
110
104
  if klass.method_defined?(name) || klass.private_method_defined?(name)
111
- if sup.method_defined?(name) || sup.private_method_defined?(name)
112
- klass.instance_method(name).owner != sup.instance_method(name).owner
105
+ if superklass.method_defined?(name) || superklass.private_method_defined?(name)
106
+ klass.instance_method(name).owner != superklass.instance_method(name).owner
113
107
  else
114
108
  true
115
109
  end
@@ -118,158 +112,309 @@ module ActiveRecord
118
112
  end
119
113
  end
120
114
 
121
- def attribute_method?(attribute)
122
- super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, '')))
115
+ # A class method is 'dangerous' if it is already (re)defined by Active Record, but
116
+ # not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
117
+ def dangerous_class_method?(method_name)
118
+ RESTRICTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
123
119
  end
124
120
 
125
- # Returns an array of column names as strings if it's not
126
- # an abstract class and table exists.
127
- # Otherwise it returns an empty array.
128
- def attribute_names
129
- @attribute_names ||= if !abstract_class? && table_exists?
130
- column_names
121
+ def class_method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
122
+ if klass.respond_to?(name, true)
123
+ if superklass.respond_to?(name, true)
124
+ klass.method(name).owner != superklass.method(name).owner
131
125
  else
132
- []
126
+ true
133
127
  end
128
+ else
129
+ false
130
+ end
134
131
  end
135
- end
136
132
 
137
- # If we haven't generated any methods yet, generate them, then
138
- # see if we've created the method we're looking for.
139
- def method_missing(method, *args, &block)
140
- unless self.class.attribute_methods_generated?
141
- self.class.define_attribute_methods
133
+ # Returns +true+ if +attribute+ is an attribute method and table exists,
134
+ # +false+ otherwise.
135
+ #
136
+ # class Person < ActiveRecord::Base
137
+ # end
138
+ #
139
+ # Person.attribute_method?('name') # => true
140
+ # Person.attribute_method?(:age=) # => true
141
+ # Person.attribute_method?(:nothing) # => false
142
+ def attribute_method?(attribute)
143
+ super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, "")))
144
+ end
142
145
 
143
- if respond_to_without_attributes?(method)
144
- send(method, *args, &block)
146
+ # Returns an array of column names as strings if it's not an abstract class and
147
+ # table exists. Otherwise it returns an empty array.
148
+ #
149
+ # class Person < ActiveRecord::Base
150
+ # end
151
+ #
152
+ # Person.attribute_names
153
+ # # => ["id", "created_at", "updated_at", "name", "age"]
154
+ def attribute_names
155
+ @attribute_names ||= if !abstract_class? && table_exists?
156
+ attribute_types.keys
145
157
  else
146
- super
158
+ []
147
159
  end
148
- else
149
- super
150
160
  end
151
- end
152
161
 
153
- def attribute_missing(match, *args, &block)
154
- if self.class.columns_hash[match.attr_name]
155
- ActiveSupport::Deprecation.warn(
156
- "The method `#{match.method_name}', matching the attribute `#{match.attr_name}' has " \
157
- "dispatched through method_missing. This shouldn't happen, because `#{match.attr_name}' " \
158
- "is a column of the table. If this error has happened through normal usage of Active " \
159
- "Record (rather than through your own code or external libraries), please report it as " \
160
- "a bug."
161
- )
162
+ # Returns true if the given attribute exists, otherwise false.
163
+ #
164
+ # class Person < ActiveRecord::Base
165
+ # end
166
+ #
167
+ # Person.has_attribute?('name') # => true
168
+ # Person.has_attribute?(:age) # => true
169
+ # Person.has_attribute?(:nothing) # => false
170
+ def has_attribute?(attr_name)
171
+ attribute_types.key?(attr_name.to_s)
162
172
  end
163
173
 
164
- super
174
+ # Returns the column object for the named attribute.
175
+ # Returns a +ActiveRecord::ConnectionAdapters::NullColumn+ if the
176
+ # named attribute does not exist.
177
+ #
178
+ # class Person < ActiveRecord::Base
179
+ # end
180
+ #
181
+ # person = Person.new
182
+ # person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
183
+ # # => #<ActiveRecord::ConnectionAdapters::Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...>
184
+ #
185
+ # person.column_for_attribute(:nothing)
186
+ # # => #<ActiveRecord::ConnectionAdapters::NullColumn:0xXXX @name=nil, @sql_type=nil, @cast_type=#<Type::Value>, ...>
187
+ def column_for_attribute(name)
188
+ name = name.to_s
189
+ columns_hash.fetch(name) do
190
+ ConnectionAdapters::NullColumn.new(name)
191
+ end
192
+ end
165
193
  end
166
194
 
195
+ # A Person object with a name attribute can ask <tt>person.respond_to?(:name)</tt>,
196
+ # <tt>person.respond_to?(:name=)</tt>, and <tt>person.respond_to?(:name?)</tt>
197
+ # which will all return +true+. It also defines the attribute methods if they have
198
+ # not been generated.
199
+ #
200
+ # class Person < ActiveRecord::Base
201
+ # end
202
+ #
203
+ # person = Person.new
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
167
211
  def respond_to?(name, include_private = false)
168
- self.class.define_attribute_methods unless self.class.attribute_methods_generated?
169
- super
212
+ return false unless super
213
+
214
+ # If the result is true then check for the select case.
215
+ # For queries selecting a subset of columns, return false for unselected columns.
216
+ # We check defined?(@attributes) not to issue warnings if called on objects that
217
+ # have been allocated but not yet initialized.
218
+ if defined?(@attributes)
219
+ if name = self.class.symbol_column_to_string(name.to_sym)
220
+ return has_attribute?(name)
221
+ end
222
+ end
223
+
224
+ true
170
225
  end
171
226
 
172
- # Returns true if the given attribute is in the attributes hash
227
+ # Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
228
+ #
229
+ # class Person < ActiveRecord::Base
230
+ # end
231
+ #
232
+ # person = Person.new
233
+ # person.has_attribute?(:name) # => true
234
+ # person.has_attribute?('age') # => true
235
+ # person.has_attribute?(:nothing) # => false
173
236
  def has_attribute?(attr_name)
174
- @attributes.has_key?(attr_name.to_s)
237
+ @attributes.key?(attr_name.to_s)
175
238
  end
176
239
 
177
240
  # Returns an array of names for the attributes available on this object.
241
+ #
242
+ # class Person < ActiveRecord::Base
243
+ # end
244
+ #
245
+ # person = Person.new
246
+ # person.attribute_names
247
+ # # => ["id", "created_at", "updated_at", "name", "age"]
178
248
  def attribute_names
179
249
  @attributes.keys
180
250
  end
181
251
 
182
252
  # Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
253
+ #
254
+ # class Person < ActiveRecord::Base
255
+ # end
256
+ #
257
+ # person = Person.create(name: 'Francesco', age: 22)
258
+ # person.attributes
259
+ # # => {"id"=>3, "created_at"=>Sun, 21 Oct 2012 04:53:04, "updated_at"=>Sun, 21 Oct 2012 04:53:04, "name"=>"Francesco", "age"=>22}
183
260
  def attributes
184
- attrs = {}
185
- attribute_names.each { |name| attrs[name] = read_attribute(name) }
186
- attrs
261
+ @attributes.to_hash
187
262
  end
188
263
 
189
264
  # Returns an <tt>#inspect</tt>-like string for the value of the
190
- # attribute +attr_name+. String attributes are truncated upto 50
191
- # characters, and Date and Time attributes are returned in the
265
+ # attribute +attr_name+. String attributes are truncated up to 50
266
+ # characters, Date and Time attributes are returned in the
192
267
  # <tt>:db</tt> format. Other attributes return the value of
193
268
  # <tt>#inspect</tt> without modification.
194
269
  #
195
- # person = Person.create!(:name => "David Heinemeier Hansson " * 3)
270
+ # person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
196
271
  #
197
272
  # person.attribute_for_inspect(:name)
198
- # # => '"David Heinemeier Hansson David Heinemeier Hansson D..."'
273
+ # # => "\"David Heinemeier Hansson David Heinemeier Hansson ...\""
199
274
  #
200
275
  # person.attribute_for_inspect(:created_at)
201
- # # => '"2009-01-12 04:48:57"'
276
+ # # => "\"2012-10-22 00:15:07\""
277
+ #
278
+ # person.attribute_for_inspect(:tag_ids)
279
+ # # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
202
280
  def attribute_for_inspect(attr_name)
203
- value = read_attribute(attr_name)
204
-
205
- if value.is_a?(String) && value.length > 50
206
- "#{value[0..50]}...".inspect
207
- elsif value.is_a?(Date) || value.is_a?(Time)
208
- %("#{value.to_s(:db)}")
209
- else
210
- value.inspect
211
- end
281
+ value = _read_attribute(attr_name)
282
+ format_for_inspect(value)
212
283
  end
213
284
 
214
- # Returns true if the specified +attribute+ has been set by the user or by a database load and is neither
215
- # nil nor empty? (the latter only applies to objects that respond to empty?, most notably Strings).
285
+ # Returns +true+ if the specified +attribute+ has been set by the user or by a
286
+ # database load and is neither +nil+ nor <tt>empty?</tt> (the latter only applies
287
+ # to objects that respond to <tt>empty?</tt>, most notably Strings). Otherwise, +false+.
288
+ # Note that it always returns +true+ with boolean attributes.
289
+ #
290
+ # class Task < ActiveRecord::Base
291
+ # end
292
+ #
293
+ # task = Task.new(title: '', is_done: false)
294
+ # task.attribute_present?(:title) # => false
295
+ # task.attribute_present?(:is_done) # => true
296
+ # task.title = 'Buy milk'
297
+ # task.is_done = true
298
+ # task.attribute_present?(:title) # => true
299
+ # task.attribute_present?(:is_done) # => true
216
300
  def attribute_present?(attribute)
217
- value = read_attribute(attribute)
301
+ value = _read_attribute(attribute)
218
302
  !value.nil? && !(value.respond_to?(:empty?) && value.empty?)
219
303
  end
220
304
 
221
- # Returns the column object for the named attribute.
222
- def column_for_attribute(name)
223
- self.class.columns_hash[name.to_s]
305
+ # Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
306
+ # "2004-12-12" in a date column is cast to a date object, like Date.new(2004, 12, 12)). It raises
307
+ # <tt>ActiveModel::MissingAttributeError</tt> if the identified attribute is missing.
308
+ #
309
+ # Note: +:id+ is always present.
310
+ #
311
+ # class Person < ActiveRecord::Base
312
+ # belongs_to :organization
313
+ # end
314
+ #
315
+ # person = Person.new(name: 'Francesco', age: '22')
316
+ # person[:name] # => "Francesco"
317
+ # person[:age] # => 22
318
+ #
319
+ # person = Person.select('id').first
320
+ # person[:name] # => ActiveModel::MissingAttributeError: missing attribute: name
321
+ # person[:organization_id] # => ActiveModel::MissingAttributeError: missing attribute: organization_id
322
+ def [](attr_name)
323
+ read_attribute(attr_name) { |n| missing_attribute(n, caller) }
224
324
  end
225
325
 
226
- protected
227
-
228
- def clone_attributes(reader_method = :read_attribute, attributes = {})
229
- attribute_names.each do |name|
230
- attributes[name] = clone_attribute_value(reader_method, name)
231
- end
232
- attributes
326
+ # Updates the attribute identified by <tt>attr_name</tt> with the specified +value+.
327
+ # (Alias for the protected #write_attribute method).
328
+ #
329
+ # class Person < ActiveRecord::Base
330
+ # end
331
+ #
332
+ # person = Person.new
333
+ # person[:age] = '22'
334
+ # person[:age] # => 22
335
+ # person[:age].class # => Integer
336
+ def []=(attr_name, value)
337
+ write_attribute(attr_name, value)
233
338
  end
234
339
 
235
- def clone_attribute_value(reader_method, attribute_name)
236
- value = send(reader_method, attribute_name)
237
- value.duplicable? ? value.clone : value
238
- rescue TypeError, NoMethodError
239
- value
340
+ # Returns the name of all database fields which have been read from this
341
+ # model. This can be useful in development mode to determine which fields
342
+ # need to be selected. For performance critical pages, selecting only the
343
+ # required fields can be an easy performance win (assuming you aren't using
344
+ # all of the fields on the model).
345
+ #
346
+ # For example:
347
+ #
348
+ # class PostsController < ActionController::Base
349
+ # after_action :print_accessed_fields, only: :index
350
+ #
351
+ # def index
352
+ # @posts = Post.all
353
+ # end
354
+ #
355
+ # private
356
+ #
357
+ # def print_accessed_fields
358
+ # p @posts.first.accessed_fields
359
+ # end
360
+ # end
361
+ #
362
+ # Which allows you to quickly change your code to:
363
+ #
364
+ # class PostsController < ActionController::Base
365
+ # def index
366
+ # @posts = Post.select(:id, :title, :author_id, :updated_at)
367
+ # end
368
+ # end
369
+ def accessed_fields
370
+ @attributes.accessed
240
371
  end
241
372
 
242
- # Returns a copy of the attributes hash where all the values have been safely quoted for use in
243
- # an Arel insert/update method.
244
- def arel_attributes_values(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
245
- attrs = {}
246
- klass = self.class
247
- arel_table = klass.arel_table
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
248
378
 
249
- attribute_names.each do |name|
250
- if (column = column_for_attribute(name)) && (include_primary_key || !column.primary)
379
+ def attributes_with_values(attribute_names)
380
+ attribute_names.each_with_object({}) do |name, attrs|
381
+ attrs[name] = _read_attribute(name)
382
+ end
383
+ end
251
384
 
252
- if include_readonly_attributes || !self.class.readonly_attributes.include?(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
391
+ end
253
392
 
254
- value = if klass.serialized_attributes.include?(name)
255
- @attributes[name].serialized_value
256
- else
257
- # FIXME: we need @attributes to be used consistently.
258
- # If the values stored in @attributes were already type
259
- # casted, this code could be simplified
260
- read_attribute(name)
261
- end
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
400
+ end
262
401
 
263
- attrs[arel_table[name]] = value
264
- 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
265
409
  end
266
410
  end
267
411
 
268
- attrs
269
- end
412
+ def readonly_attribute?(name)
413
+ self.class.readonly_attributes.include?(name)
414
+ end
270
415
 
271
- def attribute_method?(attr_name)
272
- attr_name == 'id' || (defined?(@attributes) && @attributes.include?(attr_name))
273
- end
416
+ def pk_attribute?(name)
417
+ name == @primary_key
418
+ end
274
419
  end
275
420
  end