activerecord 4.2.11.3 → 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 (372) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +613 -1643
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +13 -12
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record.rb +41 -22
  8. data/lib/active_record/aggregations.rb +267 -251
  9. data/lib/active_record/association_relation.rb +11 -6
  10. data/lib/active_record/associations.rb +1737 -1597
  11. data/lib/active_record/associations/alias_tracker.rb +29 -35
  12. data/lib/active_record/associations/association.rb +125 -58
  13. data/lib/active_record/associations/association_scope.rb +103 -132
  14. data/lib/active_record/associations/belongs_to_association.rb +65 -60
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -40
  17. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  18. data/lib/active_record/associations/builder/collection_association.rb +10 -33
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +52 -66
  20. data/lib/active_record/associations/builder/has_many.rb +8 -4
  21. data/lib/active_record/associations/builder/has_one.rb +46 -5
  22. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  23. data/lib/active_record/associations/collection_association.rb +131 -287
  24. data/lib/active_record/associations/collection_proxy.rb +241 -146
  25. data/lib/active_record/associations/foreign_association.rb +10 -1
  26. data/lib/active_record/associations/has_many_association.rb +34 -97
  27. data/lib/active_record/associations/has_many_through_association.rb +60 -87
  28. data/lib/active_record/associations/has_one_association.rb +61 -49
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +137 -167
  31. data/lib/active_record/associations/join_dependency/join_association.rb +38 -86
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +90 -92
  35. data/lib/active_record/associations/preloader/association.rb +90 -123
  36. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  37. data/lib/active_record/associations/singular_association.rb +18 -39
  38. data/lib/active_record/associations/through_association.rb +38 -18
  39. data/lib/active_record/attribute_assignment.rb +56 -183
  40. data/lib/active_record/attribute_decorators.rb +39 -15
  41. data/lib/active_record/attribute_methods.rb +120 -135
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -8
  43. data/lib/active_record/attribute_methods/dirty.rb +174 -144
  44. data/lib/active_record/attribute_methods/primary_key.rb +91 -83
  45. data/lib/active_record/attribute_methods/query.rb +6 -5
  46. data/lib/active_record/attribute_methods/read.rb +20 -76
  47. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +58 -36
  49. data/lib/active_record/attribute_methods/write.rb +32 -54
  50. data/lib/active_record/attributes.rb +214 -82
  51. data/lib/active_record/autosave_association.rb +91 -37
  52. data/lib/active_record/base.rb +57 -45
  53. data/lib/active_record/callbacks.rb +100 -74
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +24 -12
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -296
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -115
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +356 -227
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +664 -243
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -83
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +460 -204
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +510 -635
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +58 -180
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -114
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -58
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
  93. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  95. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  96. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  101. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  102. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  103. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
  106. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +470 -290
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +551 -356
  117. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +290 -345
  127. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  128. data/lib/active_record/connection_handling.rb +176 -41
  129. data/lib/active_record/core.rb +251 -231
  130. data/lib/active_record/counter_cache.rb +67 -49
  131. data/lib/active_record/database_configurations.rb +233 -0
  132. data/lib/active_record/database_configurations/database_config.rb +37 -0
  133. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  134. data/lib/active_record/database_configurations/url_config.rb +79 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -105
  137. data/lib/active_record/enum.rb +163 -86
  138. data/lib/active_record/errors.rb +188 -53
  139. data/lib/active_record/explain.rb +23 -11
  140. data/lib/active_record/explain_registry.rb +4 -2
  141. data/lib/active_record/explain_subscriber.rb +10 -5
  142. data/lib/active_record/fixture_set/file.rb +35 -9
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +153 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  147. data/lib/active_record/fixtures.rb +228 -499
  148. data/lib/active_record/gem_version.rb +6 -4
  149. data/lib/active_record/inheritance.rb +158 -112
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +123 -29
  152. data/lib/active_record/internal_metadata.rb +53 -0
  153. data/lib/active_record/legacy_yaml_adapter.rb +21 -3
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +87 -96
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +76 -33
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  160. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  161. data/lib/active_record/migration.rb +621 -303
  162. data/lib/active_record/migration/command_recorder.rb +177 -90
  163. data/lib/active_record/migration/compatibility.rb +244 -0
  164. data/lib/active_record/migration/join_table.rb +8 -6
  165. data/lib/active_record/model_schema.rb +312 -112
  166. data/lib/active_record/nested_attributes.rb +264 -222
  167. data/lib/active_record/no_touching.rb +14 -1
  168. data/lib/active_record/null_relation.rb +24 -37
  169. data/lib/active_record/persistence.rb +557 -125
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +43 -29
  172. data/lib/active_record/railtie.rb +143 -44
  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 +328 -185
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +428 -279
  179. data/lib/active_record/relation.rb +518 -341
  180. data/lib/active_record/relation/batches.rb +207 -55
  181. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  182. data/lib/active_record/relation/calculations.rb +267 -253
  183. data/lib/active_record/relation/delegation.rb +70 -80
  184. data/lib/active_record/relation/finder_methods.rb +277 -241
  185. data/lib/active_record/relation/from_clause.rb +26 -0
  186. data/lib/active_record/relation/merger.rb +78 -87
  187. data/lib/active_record/relation/predicate_builder.rb +114 -119
  188. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
  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 +18 -0
  191. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  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 +22 -0
  194. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  195. data/lib/active_record/relation/query_attribute.rb +50 -0
  196. data/lib/active_record/relation/query_methods.rb +575 -394
  197. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  198. data/lib/active_record/relation/spawn_methods.rb +11 -13
  199. data/lib/active_record/relation/where_clause.rb +190 -0
  200. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  201. data/lib/active_record/result.rb +79 -42
  202. data/lib/active_record/runtime_registry.rb +6 -4
  203. data/lib/active_record/sanitization.rb +144 -121
  204. data/lib/active_record/schema.rb +21 -24
  205. data/lib/active_record/schema_dumper.rb +112 -93
  206. data/lib/active_record/schema_migration.rb +24 -17
  207. data/lib/active_record/scoping.rb +45 -26
  208. data/lib/active_record/scoping/default.rb +101 -85
  209. data/lib/active_record/scoping/named.rb +86 -33
  210. data/lib/active_record/secure_token.rb +40 -0
  211. data/lib/active_record/serialization.rb +5 -5
  212. data/lib/active_record/statement_cache.rb +73 -36
  213. data/lib/active_record/store.rb +127 -42
  214. data/lib/active_record/suppressor.rb +61 -0
  215. data/lib/active_record/table_metadata.rb +75 -0
  216. data/lib/active_record/tasks/database_tasks.rb +307 -100
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +55 -99
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -41
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +224 -0
  222. data/lib/active_record/timestamp.rb +86 -40
  223. data/lib/active_record/touch_later.rb +66 -0
  224. data/lib/active_record/transactions.rb +216 -150
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type.rb +78 -23
  227. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  228. data/lib/active_record/type/date.rb +4 -45
  229. data/lib/active_record/type/date_time.rb +4 -49
  230. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  231. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  232. data/lib/active_record/type/internal/timezone.rb +17 -0
  233. data/lib/active_record/type/json.rb +30 -0
  234. data/lib/active_record/type/serialized.rb +24 -15
  235. data/lib/active_record/type/text.rb +2 -2
  236. data/lib/active_record/type/time.rb +11 -16
  237. data/lib/active_record/type/type_map.rb +15 -17
  238. data/lib/active_record/type/unsigned_integer.rb +9 -7
  239. data/lib/active_record/type_caster.rb +9 -0
  240. data/lib/active_record/type_caster/connection.rb +34 -0
  241. data/lib/active_record/type_caster/map.rb +20 -0
  242. data/lib/active_record/validations.rb +39 -35
  243. data/lib/active_record/validations/absence.rb +25 -0
  244. data/lib/active_record/validations/associated.rb +13 -4
  245. data/lib/active_record/validations/length.rb +26 -0
  246. data/lib/active_record/validations/presence.rb +14 -13
  247. data/lib/active_record/validations/uniqueness.rb +42 -55
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/arel.rb +51 -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 +257 -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 +204 -0
  317. data/lib/arel/visitors/dot.rb +297 -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 +157 -0
  321. data/lib/arel/visitors/mysql.rb +83 -0
  322. data/lib/arel/visitors/oracle.rb +159 -0
  323. data/lib/arel/visitors/oracle12.rb +66 -0
  324. data/lib/arel/visitors/postgresql.rb +110 -0
  325. data/lib/arel/visitors/sqlite.rb +39 -0
  326. data/lib/arel/visitors/to_sql.rb +889 -0
  327. data/lib/arel/visitors/visitor.rb +46 -0
  328. data/lib/arel/visitors/where_sql.rb +23 -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 +27 -0
  332. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  333. data/lib/rails/generators/active_record/migration.rb +31 -1
  334. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  335. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  336. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
  337. data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  340. metadata +164 -59
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  348. data/lib/active_record/attribute.rb +0 -163
  349. data/lib/active_record/attribute_set.rb +0 -81
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
  352. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  353. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  354. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  355. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  356. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  359. data/lib/active_record/type/big_integer.rb +0 -13
  360. data/lib/active_record/type/binary.rb +0 -50
  361. data/lib/active_record/type/boolean.rb +0 -31
  362. data/lib/active_record/type/decimal.rb +0 -64
  363. data/lib/active_record/type/decorator.rb +0 -14
  364. data/lib/active_record/type/float.rb +0 -19
  365. data/lib/active_record/type/integer.rb +0 -59
  366. data/lib/active_record/type/mutable.rb +0 -16
  367. data/lib/active_record/type/numeric.rb +0 -36
  368. data/lib/active_record/type/string.rb +0 -40
  369. data/lib/active_record/type/time_value.rb +0 -38
  370. data/lib/active_record/type/value.rb +0 -110
  371. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  372. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,68 +1,90 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module AttributeMethods
3
5
  module TimeZoneConversion
4
6
  class TimeZoneConverter < DelegateClass(Type::Value) # :nodoc:
5
- include Type::Decorator
6
-
7
- def type_cast_from_database(value)
7
+ def deserialize(value)
8
8
  convert_time_to_time_zone(super)
9
9
  end
10
10
 
11
- def type_cast_from_user(value)
12
- if value.is_a?(Array)
13
- value.map { |v| type_cast_from_user(v) }
11
+ def cast(value)
12
+ return if value.nil?
13
+
14
+ if value.is_a?(Hash)
15
+ set_time_zone_without_conversion(super)
14
16
  elsif value.respond_to?(:in_time_zone)
15
17
  begin
16
- value.in_time_zone || super
18
+ super(user_input_in_time_zone(value)) || super
17
19
  rescue ArgumentError
18
20
  nil
19
21
  end
22
+ else
23
+ map_avoiding_infinite_recursion(super) { |v| cast(v) }
20
24
  end
21
25
  end
22
26
 
23
- def convert_time_to_time_zone(value)
24
- if value.is_a?(Array)
25
- value.map { |v| convert_time_to_time_zone(v) }
26
- elsif value.acts_like?(:time)
27
- value.in_time_zone
28
- else
29
- value
27
+ private
28
+
29
+ def convert_time_to_time_zone(value)
30
+ return if value.nil?
31
+
32
+ if value.acts_like?(:time)
33
+ value.in_time_zone
34
+ elsif value.is_a?(::Float)
35
+ value
36
+ else
37
+ map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) }
38
+ end
39
+ end
40
+
41
+ def set_time_zone_without_conversion(value)
42
+ ::Time.zone.local_to_utc(value).try(:in_time_zone) if value
43
+ end
44
+
45
+ def map_avoiding_infinite_recursion(value)
46
+ map(value) do |v|
47
+ if value.equal?(v)
48
+ nil
49
+ else
50
+ yield(v)
51
+ end
52
+ end
30
53
  end
31
- end
32
54
  end
33
55
 
34
56
  extend ActiveSupport::Concern
35
57
 
36
58
  included do
37
- mattr_accessor :time_zone_aware_attributes, instance_writer: false
38
- self.time_zone_aware_attributes = false
59
+ mattr_accessor :time_zone_aware_attributes, instance_writer: false, default: false
39
60
 
40
- class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false
41
- self.skip_time_zone_conversion_for_attributes = []
61
+ class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false, default: []
62
+ class_attribute :time_zone_aware_types, instance_writer: false, default: [ :datetime, :time ]
42
63
  end
43
64
 
44
- module ClassMethods
65
+ module ClassMethods # :nodoc:
45
66
  private
46
67
 
47
- def inherited(subclass)
48
- # We need to apply this decorator here, rather than on module inclusion. The closure
49
- # created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the
50
- # sub class being decorated. As such, changes to `time_zone_aware_attributes`, or
51
- # `skip_time_zone_conversion_for_attributes` would not be picked up.
52
- subclass.class_eval do
53
- matcher = ->(name, type) { create_time_zone_conversion_attribute?(name, type) }
54
- decorate_matching_attribute_types(matcher, :_time_zone_conversion) do |type|
55
- TimeZoneConverter.new(type)
68
+ def inherited(subclass)
69
+ super
70
+ # We need to apply this decorator here, rather than on module inclusion. The closure
71
+ # created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the
72
+ # sub class being decorated. As such, changes to `time_zone_aware_attributes`, or
73
+ # `skip_time_zone_conversion_for_attributes` would not be picked up.
74
+ subclass.class_eval do
75
+ matcher = ->(name, type) { create_time_zone_conversion_attribute?(name, type) }
76
+ decorate_matching_attribute_types(matcher, "_time_zone_conversion") do |type|
77
+ TimeZoneConverter.new(type)
78
+ end
56
79
  end
57
80
  end
58
- super
59
- end
60
81
 
61
- def create_time_zone_conversion_attribute?(name, cast_type)
62
- time_zone_aware_attributes &&
63
- !self.skip_time_zone_conversion_for_attributes.include?(name.to_sym) &&
64
- (:datetime == cast_type.type)
65
- end
82
+ def create_time_zone_conversion_attribute?(name, cast_type)
83
+ enabled_for_column = time_zone_aware_attributes &&
84
+ !skip_time_zone_conversion_for_attributes.include?(name.to_sym)
85
+
86
+ enabled_for_column && time_zone_aware_types.include?(cast_type.type)
87
+ end
66
88
  end
67
89
  end
68
90
  end
@@ -1,83 +1,61 @@
1
- require 'active_support/core_ext/module/method_transplanting'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
4
  module AttributeMethods
5
5
  module Write
6
- WriterMethodCache = Class.new(AttributeMethodCache) {
7
- private
8
-
9
- def method_body(method_name, const_name)
10
- <<-EOMETHOD
11
- def #{method_name}(value)
12
- name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{const_name}
13
- write_attribute(name, value)
14
- end
15
- EOMETHOD
16
- end
17
- }.new
18
-
19
6
  extend ActiveSupport::Concern
20
7
 
21
8
  included do
22
9
  attribute_method_suffix "="
23
10
  end
24
11
 
25
- module ClassMethods
26
- protected
12
+ module ClassMethods # :nodoc:
13
+ private
27
14
 
28
- if Module.methods_transplantable?
29
- def define_method_attribute=(name)
30
- method = WriterMethodCache[name]
31
- generated_attribute_methods.module_eval {
32
- define_method "#{name}=", method
33
- }
34
- end
35
- else
36
15
  def define_method_attribute=(name)
37
- safe_name = name.unpack('h*').first
38
- ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
39
-
40
- generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
41
- def __temp__#{safe_name}=(value)
42
- name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
43
- write_attribute(name, value)
44
- end
45
- alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
46
- undef_method :__temp__#{safe_name}=
47
- STR
16
+ ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
17
+ generated_attribute_methods, name, writer: true,
18
+ ) do |temp_method_name, attr_name_expr|
19
+ generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
20
+ def #{temp_method_name}(value)
21
+ name = #{attr_name_expr}
22
+ _write_attribute(name, value)
23
+ end
24
+ RUBY
25
+ end
48
26
  end
49
- end
50
27
  end
51
28
 
52
29
  # Updates the attribute identified by <tt>attr_name</tt> with the
53
30
  # specified +value+. Empty strings for Integer and Float columns are
54
31
  # turned into +nil+.
55
32
  def write_attribute(attr_name, value)
56
- write_attribute_with_type_cast(attr_name, value, true)
57
- end
33
+ name = attr_name.to_s
34
+ name = self.class.attribute_aliases[name] || name
58
35
 
59
- def raw_write_attribute(attr_name, value)
60
- write_attribute_with_type_cast(attr_name, value, false)
36
+ name = @primary_key if name == "id" && @primary_key
37
+ _write_attribute(name, value)
61
38
  end
62
39
 
63
- private
64
- # Handle *= for method_missing.
65
- def attribute=(attribute_name, value)
66
- write_attribute(attribute_name, value)
40
+ # This method exists to avoid the expensive primary_key check internally, without
41
+ # breaking compatibility with the write_attribute API
42
+ def _write_attribute(attr_name, value) # :nodoc:
43
+ sync_with_transaction_state if @transaction_state&.finalized?
44
+ @attributes.write_from_user(attr_name.to_s, value)
45
+ value
67
46
  end
68
47
 
69
- def write_attribute_with_type_cast(attr_name, value, should_type_cast)
70
- attr_name = attr_name.to_s
71
- attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key
72
-
73
- if should_type_cast
74
- @attributes.write_from_user(attr_name, value)
75
- else
76
- @attributes.write_cast_value(attr_name, value)
48
+ private
49
+ def write_attribute_without_type_cast(attr_name, value)
50
+ sync_with_transaction_state if @transaction_state&.finalized?
51
+ @attributes.write_cast_value(attr_name.to_s, value)
52
+ value
77
53
  end
78
54
 
79
- value
80
- end
55
+ # Dispatch target for <tt>*=</tt> attribute methods.
56
+ def attribute=(attribute_name, value)
57
+ _write_attribute(attribute_name, value)
58
+ end
81
59
  end
82
60
  end
83
61
  end
@@ -1,33 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_model/attribute/user_provided_default"
4
+
1
5
  module ActiveRecord
2
- module Attributes # :nodoc:
6
+ # See ActiveRecord::Attributes::ClassMethods for documentation
7
+ module Attributes
3
8
  extend ActiveSupport::Concern
4
9
 
5
- Type = ActiveRecord::Type
6
-
7
10
  included do
8
- class_attribute :user_provided_columns, instance_accessor: false # :internal:
9
- class_attribute :user_provided_defaults, instance_accessor: false # :internal:
10
- self.user_provided_columns = {}
11
- self.user_provided_defaults = {}
12
-
13
- delegate :persistable_attribute_names, to: :class
11
+ class_attribute :attributes_to_define_after_schema_loads, instance_accessor: false, default: {} # :internal:
14
12
  end
15
13
 
16
- module ClassMethods # :nodoc:
17
- # Defines or overrides a attribute on this model. This allows customization of
18
- # Active Record's type casting behavior, as well as adding support for user defined
19
- # types.
14
+ module ClassMethods
15
+ # Defines an attribute with a type on this model. It will override the
16
+ # type of existing attributes if needed. This allows control over how
17
+ # values are converted to and from SQL when assigned to a model. It also
18
+ # changes the behavior of values passed to
19
+ # {ActiveRecord::Base.where}[rdoc-ref:QueryMethods#where]. This will let you use
20
+ # your domain objects across much of Active Record, without having to
21
+ # rely on implementation details or monkey patching.
20
22
  #
21
- # +name+ The name of the methods to define attribute methods for, and the column which
22
- # this will persist to.
23
+ # +name+ The name of the methods to define attribute methods for, and the
24
+ # column which this will persist to.
23
25
  #
24
- # +cast_type+ A type object that contains information about how to type cast the value.
25
- # See the examples section for more information.
26
+ # +cast_type+ A symbol such as +:string+ or +:integer+, or a type object
27
+ # to be used for this attribute. See the examples below for more
28
+ # information about providing custom type objects.
26
29
  #
27
30
  # ==== Options
28
- # The options hash accepts the following options:
29
31
  #
30
- # +default+ is the default value that the column should use on a new record.
32
+ # The following options are accepted:
33
+ #
34
+ # +default+ The default value to use when no value is provided. If this option
35
+ # is not passed, the previous default value (if any) will be used.
36
+ # Otherwise, the default will be +nil+.
37
+ #
38
+ # +array+ (PostgreSQL only) specifies that the type should be an array (see the
39
+ # examples below).
40
+ #
41
+ # +range+ (PostgreSQL only) specifies that the type should be a range (see the
42
+ # examples below).
43
+ #
44
+ # When using a symbol for +cast_type+, extra options are forwarded to the
45
+ # constructor of the type object.
31
46
  #
32
47
  # ==== Examples
33
48
  #
@@ -45,103 +60,220 @@ module ActiveRecord
45
60
  # store_listing = StoreListing.new(price_in_cents: '10.1')
46
61
  #
47
62
  # # before
48
- # store_listing.price_in_cents # => BigDecimal.new(10.1)
63
+ # store_listing.price_in_cents # => BigDecimal(10.1)
49
64
  #
50
65
  # class StoreListing < ActiveRecord::Base
51
- # attribute :price_in_cents, Type::Integer.new
66
+ # attribute :price_in_cents, :integer
52
67
  # end
53
68
  #
54
69
  # # after
55
70
  # store_listing.price_in_cents # => 10
56
71
  #
57
- # Users may also define their own custom types, as long as they respond to the methods
58
- # defined on the value type. The `type_cast` method on your type object will be called
59
- # with values both from the database, and from your controllers. See
60
- # `ActiveRecord::Attributes::Type::Value` for the expected API. It is recommended that your
61
- # type objects inherit from an existing type, or the base value type.
72
+ # A default can also be provided.
73
+ #
74
+ # # db/schema.rb
75
+ # create_table :store_listings, force: true do |t|
76
+ # t.string :my_string, default: "original default"
77
+ # end
78
+ #
79
+ # StoreListing.new.my_string # => "original default"
80
+ #
81
+ # # app/models/store_listing.rb
82
+ # class StoreListing < ActiveRecord::Base
83
+ # attribute :my_string, :string, default: "new default"
84
+ # end
85
+ #
86
+ # StoreListing.new.my_string # => "new default"
87
+ #
88
+ # class Product < ActiveRecord::Base
89
+ # attribute :my_default_proc, :datetime, default: -> { Time.now }
90
+ # end
91
+ #
92
+ # Product.new.my_default_proc # => 2015-05-30 11:04:48 -0600
93
+ # sleep 1
94
+ # Product.new.my_default_proc # => 2015-05-30 11:04:49 -0600
95
+ #
96
+ # \Attributes do not need to be backed by a database column.
97
+ #
98
+ # # app/models/my_model.rb
99
+ # class MyModel < ActiveRecord::Base
100
+ # attribute :my_string, :string
101
+ # attribute :my_int_array, :integer, array: true
102
+ # attribute :my_float_range, :float, range: true
103
+ # end
104
+ #
105
+ # model = MyModel.new(
106
+ # my_string: "string",
107
+ # my_int_array: ["1", "2", "3"],
108
+ # my_float_range: "[1,3.5]",
109
+ # )
110
+ # model.attributes
111
+ # # =>
112
+ # {
113
+ # my_string: "string",
114
+ # my_int_array: [1, 2, 3],
115
+ # my_float_range: 1.0..3.5
116
+ # }
117
+ #
118
+ # Passing options to the type constructor
119
+ #
120
+ # # app/models/my_model.rb
121
+ # class MyModel < ActiveRecord::Base
122
+ # attribute :small_int, :integer, limit: 2
123
+ # end
124
+ #
125
+ # MyModel.create(small_int: 65537)
126
+ # # => Error: 65537 is out of range for the limit of two bytes
127
+ #
128
+ # ==== Creating Custom Types
129
+ #
130
+ # Users may also define their own custom types, as long as they respond
131
+ # to the methods defined on the value type. The method +deserialize+ or
132
+ # +cast+ will be called on your type object, with raw input from the
133
+ # database or from your controllers. See ActiveModel::Type::Value for the
134
+ # expected API. It is recommended that your type objects inherit from an
135
+ # existing type, or from ActiveRecord::Type::Value
62
136
  #
63
137
  # class MoneyType < ActiveRecord::Type::Integer
64
- # def type_cast(value)
65
- # if value.include?('$')
138
+ # def cast(value)
139
+ # if !value.kind_of?(Numeric) && value.include?('$')
66
140
  # price_in_dollars = value.gsub(/\$/, '').to_f
67
- # price_in_dollars * 100
141
+ # super(price_in_dollars * 100)
68
142
  # else
69
- # value.to_i
143
+ # super
70
144
  # end
71
145
  # end
72
146
  # end
73
147
  #
148
+ # # config/initializers/types.rb
149
+ # ActiveRecord::Type.register(:money, MoneyType)
150
+ #
151
+ # # app/models/store_listing.rb
74
152
  # class StoreListing < ActiveRecord::Base
75
- # attribute :price_in_cents, MoneyType.new
153
+ # attribute :price_in_cents, :money
76
154
  # end
77
155
  #
78
156
  # store_listing = StoreListing.new(price_in_cents: '$10.00')
79
157
  # store_listing.price_in_cents # => 1000
80
- def attribute(name, cast_type, options = {})
158
+ #
159
+ # For more details on creating custom types, see the documentation for
160
+ # ActiveModel::Type::Value. For more details on registering your types
161
+ # to be referenced by a symbol, see ActiveRecord::Type.register. You can
162
+ # also pass a type object directly, in place of a symbol.
163
+ #
164
+ # ==== \Querying
165
+ #
166
+ # When {ActiveRecord::Base.where}[rdoc-ref:QueryMethods#where] is called, it will
167
+ # use the type defined by the model class to convert the value to SQL,
168
+ # calling +serialize+ on your type object. For example:
169
+ #
170
+ # class Money < Struct.new(:amount, :currency)
171
+ # end
172
+ #
173
+ # class MoneyType < Type::Value
174
+ # def initialize(currency_converter:)
175
+ # @currency_converter = currency_converter
176
+ # end
177
+ #
178
+ # # value will be the result of +deserialize+ or
179
+ # # +cast+. Assumed to be an instance of +Money+ in
180
+ # # this case.
181
+ # def serialize(value)
182
+ # value_in_bitcoins = @currency_converter.convert_to_bitcoins(value)
183
+ # value_in_bitcoins.amount
184
+ # end
185
+ # end
186
+ #
187
+ # # config/initializers/types.rb
188
+ # ActiveRecord::Type.register(:money, MoneyType)
189
+ #
190
+ # # app/models/product.rb
191
+ # class Product < ActiveRecord::Base
192
+ # currency_converter = ConversionRatesFromTheInternet.new
193
+ # attribute :price_in_bitcoins, :money, currency_converter: currency_converter
194
+ # end
195
+ #
196
+ # Product.where(price_in_bitcoins: Money.new(5, "USD"))
197
+ # # => SELECT * FROM products WHERE price_in_bitcoins = 0.02230
198
+ #
199
+ # Product.where(price_in_bitcoins: Money.new(5, "GBP"))
200
+ # # => SELECT * FROM products WHERE price_in_bitcoins = 0.03412
201
+ #
202
+ # ==== Dirty Tracking
203
+ #
204
+ # The type of an attribute is given the opportunity to change how dirty
205
+ # tracking is performed. The methods +changed?+ and +changed_in_place?+
206
+ # will be called from ActiveModel::Dirty. See the documentation for those
207
+ # methods in ActiveModel::Type::Value for more details.
208
+ def attribute(name, cast_type = Type::Value.new, **options)
81
209
  name = name.to_s
82
- clear_caches_calculated_from_columns
83
- # Assign a new hash to ensure that subclasses do not share a hash
84
- self.user_provided_columns = user_provided_columns.merge(name => cast_type)
210
+ reload_schema_from_cache
85
211
 
86
- if options.key?(:default)
87
- self.user_provided_defaults = user_provided_defaults.merge(name => options[:default])
88
- end
89
- end
90
-
91
- # Returns an array of column objects for the table associated with this class.
92
- def columns
93
- @columns ||= add_user_provided_columns(connection.schema_cache.columns(table_name))
212
+ self.attributes_to_define_after_schema_loads =
213
+ attributes_to_define_after_schema_loads.merge(
214
+ name => [cast_type, options]
215
+ )
94
216
  end
95
217
 
96
- # Returns a hash of column objects for the table associated with this class.
97
- def columns_hash
98
- @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
99
- end
100
-
101
- def persistable_attribute_names # :nodoc:
102
- @persistable_attribute_names ||= connection.schema_cache.columns_hash(table_name).keys
218
+ # This is the low level API which sits beneath +attribute+. It only
219
+ # accepts type objects, and will do its work immediately instead of
220
+ # waiting for the schema to load. Automatic schema detection and
221
+ # ClassMethods#attribute both call this under the hood. While this method
222
+ # is provided so it can be used by plugin authors, application code
223
+ # should probably use ClassMethods#attribute.
224
+ #
225
+ # +name+ The name of the attribute being defined. Expected to be a +String+.
226
+ #
227
+ # +cast_type+ The type object to use for this attribute.
228
+ #
229
+ # +default+ The default value to use when no value is provided. If this option
230
+ # is not passed, the previous default value (if any) will be used.
231
+ # Otherwise, the default will be +nil+. A proc can also be passed, and
232
+ # will be called once each time a new value is needed.
233
+ #
234
+ # +user_provided_default+ Whether the default value should be cast using
235
+ # +cast+ or +deserialize+.
236
+ def define_attribute(
237
+ name,
238
+ cast_type,
239
+ default: NO_DEFAULT_PROVIDED,
240
+ user_provided_default: true
241
+ )
242
+ attribute_types[name] = cast_type
243
+ define_default_attribute(name, default, cast_type, from_user: user_provided_default)
103
244
  end
104
245
 
105
- def reset_column_information # :nodoc:
246
+ def load_schema! # :nodoc:
106
247
  super
107
- clear_caches_calculated_from_columns
248
+ attributes_to_define_after_schema_loads.each do |name, (type, options)|
249
+ if type.is_a?(Symbol)
250
+ type = ActiveRecord::Type.lookup(type, **options.except(:default))
251
+ end
252
+
253
+ define_attribute(name, type, **options.slice(:default))
254
+ end
108
255
  end
109
256
 
110
257
  private
111
258
 
112
- def add_user_provided_columns(schema_columns)
113
- existing_columns = schema_columns.map do |column|
114
- new_type = user_provided_columns[column.name]
115
- if new_type
116
- column.with_type(new_type)
259
+ NO_DEFAULT_PROVIDED = Object.new # :nodoc:
260
+ private_constant :NO_DEFAULT_PROVIDED
261
+
262
+ def define_default_attribute(name, value, type, from_user:)
263
+ if value == NO_DEFAULT_PROVIDED
264
+ default_attribute = _default_attributes[name].with_type(type)
265
+ elsif from_user
266
+ default_attribute = ActiveModel::Attribute::UserProvidedDefault.new(
267
+ name,
268
+ value,
269
+ type,
270
+ _default_attributes.fetch(name.to_s) { nil },
271
+ )
117
272
  else
118
- column
273
+ default_attribute = ActiveModel::Attribute.from_database(name, value, type)
119
274
  end
275
+ _default_attributes[name] = default_attribute
120
276
  end
121
-
122
- existing_column_names = existing_columns.map(&:name)
123
- new_columns = user_provided_columns.except(*existing_column_names).map do |(name, type)|
124
- connection.new_column(name, nil, type)
125
- end
126
-
127
- existing_columns + new_columns
128
- end
129
-
130
- def clear_caches_calculated_from_columns
131
- @attributes_builder = nil
132
- @column_names = nil
133
- @column_types = nil
134
- @columns = nil
135
- @columns_hash = nil
136
- @content_columns = nil
137
- @default_attributes = nil
138
- @persistable_attribute_names = nil
139
- @attribute_names = nil
140
- end
141
-
142
- def raw_default_values
143
- super.merge(user_provided_defaults)
144
- end
145
277
  end
146
278
  end
147
279
  end