activerecord 5.0.7.2 → 6.0.6.1

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

Potentially problematic release.


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

Files changed (359) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +844 -1944
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +9 -7
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +249 -247
  9. data/lib/active_record/association_relation.rb +18 -14
  10. data/lib/active_record/associations/alias_tracker.rb +24 -34
  11. data/lib/active_record/associations/association.rb +113 -55
  12. data/lib/active_record/associations/association_scope.rb +102 -96
  13. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  15. data/lib/active_record/associations/builder/association.rb +18 -25
  16. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  17. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +41 -62
  19. data/lib/active_record/associations/builder/has_many.rb +4 -0
  20. data/lib/active_record/associations/builder/has_one.rb +37 -1
  21. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  22. data/lib/active_record/associations/collection_association.rb +93 -254
  23. data/lib/active_record/associations/collection_proxy.rb +159 -122
  24. data/lib/active_record/associations/foreign_association.rb +9 -0
  25. data/lib/active_record/associations/has_many_association.rb +23 -30
  26. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  27. data/lib/active_record/associations/has_one_association.rb +59 -54
  28. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  29. data/lib/active_record/associations/join_dependency/join_association.rb +43 -85
  30. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  31. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  32. data/lib/active_record/associations/join_dependency.rb +152 -177
  33. data/lib/active_record/associations/preloader/association.rb +101 -97
  34. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  35. data/lib/active_record/associations/preloader.rb +94 -103
  36. data/lib/active_record/associations/singular_association.rb +12 -45
  37. data/lib/active_record/associations/through_association.rb +27 -15
  38. data/lib/active_record/associations.rb +1603 -1592
  39. data/lib/active_record/attribute_assignment.rb +54 -61
  40. data/lib/active_record/attribute_decorators.rb +38 -17
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
  42. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  43. data/lib/active_record/attribute_methods/primary_key.rb +85 -92
  44. data/lib/active_record/attribute_methods/query.rb +4 -3
  45. data/lib/active_record/attribute_methods/read.rb +20 -49
  46. data/lib/active_record/attribute_methods/serialization.rb +29 -7
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
  48. data/lib/active_record/attribute_methods/write.rb +34 -33
  49. data/lib/active_record/attribute_methods.rb +66 -106
  50. data/lib/active_record/attributes.rb +38 -25
  51. data/lib/active_record/autosave_association.rb +58 -39
  52. data/lib/active_record/base.rb +27 -24
  53. data/lib/active_record/callbacks.rb +64 -35
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +34 -13
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +558 -323
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +128 -75
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +233 -147
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +373 -202
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +401 -562
  69. data/lib/active_record/connection_adapters/column.rb +41 -13
  70. data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  72. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +137 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -54
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +12 -2
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  99. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +8 -4
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +20 -26
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +378 -308
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -275
  117. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  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 +261 -267
  127. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  128. data/lib/active_record/connection_handling.rb +143 -40
  129. data/lib/active_record/core.rb +207 -160
  130. data/lib/active_record/counter_cache.rb +60 -28
  131. data/lib/active_record/database_configurations/database_config.rb +37 -0
  132. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  133. data/lib/active_record/database_configurations/url_config.rb +78 -0
  134. data/lib/active_record/database_configurations.rb +233 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -87
  137. data/lib/active_record/enum.rb +67 -23
  138. data/lib/active_record/errors.rb +114 -18
  139. data/lib/active_record/explain.rb +4 -4
  140. data/lib/active_record/explain_registry.rb +3 -1
  141. data/lib/active_record/explain_subscriber.rb +9 -4
  142. data/lib/active_record/fixture_set/file.rb +13 -8
  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 +152 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  147. data/lib/active_record/fixtures.rb +194 -504
  148. data/lib/active_record/gem_version.rb +5 -3
  149. data/lib/active_record/inheritance.rb +150 -99
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +116 -25
  152. data/lib/active_record/internal_metadata.rb +16 -19
  153. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  154. data/lib/active_record/locking/optimistic.rb +85 -86
  155. data/lib/active_record/locking/pessimistic.rb +18 -6
  156. data/lib/active_record/log_subscriber.rb +48 -29
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  159. data/lib/active_record/middleware/database_selector.rb +74 -0
  160. data/lib/active_record/migration/command_recorder.rb +134 -100
  161. data/lib/active_record/migration/compatibility.rb +174 -56
  162. data/lib/active_record/migration/join_table.rb +8 -7
  163. data/lib/active_record/migration.rb +369 -302
  164. data/lib/active_record/model_schema.rb +160 -127
  165. data/lib/active_record/nested_attributes.rb +213 -202
  166. data/lib/active_record/no_touching.rb +12 -3
  167. data/lib/active_record/null_relation.rb +12 -34
  168. data/lib/active_record/persistence.rb +446 -77
  169. data/lib/active_record/query_cache.rb +13 -12
  170. data/lib/active_record/querying.rb +37 -24
  171. data/lib/active_record/railtie.rb +128 -36
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +2 -0
  174. data/lib/active_record/railties/controller_runtime.rb +34 -33
  175. data/lib/active_record/railties/databases.rake +312 -177
  176. data/lib/active_record/readonly_attributes.rb +5 -4
  177. data/lib/active_record/reflection.rb +214 -254
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  179. data/lib/active_record/relation/batches.rb +98 -52
  180. data/lib/active_record/relation/calculations.rb +212 -173
  181. data/lib/active_record/relation/delegation.rb +73 -69
  182. data/lib/active_record/relation/finder_methods.rb +207 -247
  183. data/lib/active_record/relation/from_clause.rb +6 -8
  184. data/lib/active_record/relation/merger.rb +82 -61
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  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 +4 -3
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  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 +7 -18
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  192. data/lib/active_record/relation/predicate_builder.rb +83 -105
  193. data/lib/active_record/relation/query_attribute.rb +33 -2
  194. data/lib/active_record/relation/query_methods.rb +488 -332
  195. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  196. data/lib/active_record/relation/spawn_methods.rb +8 -8
  197. data/lib/active_record/relation/where_clause.rb +111 -96
  198. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  199. data/lib/active_record/relation.rb +443 -318
  200. data/lib/active_record/result.rb +69 -40
  201. data/lib/active_record/runtime_registry.rb +5 -3
  202. data/lib/active_record/sanitization.rb +83 -99
  203. data/lib/active_record/schema.rb +7 -14
  204. data/lib/active_record/schema_dumper.rb +71 -69
  205. data/lib/active_record/schema_migration.rb +16 -6
  206. data/lib/active_record/scoping/default.rb +92 -95
  207. data/lib/active_record/scoping/named.rb +51 -26
  208. data/lib/active_record/scoping.rb +20 -20
  209. data/lib/active_record/secure_token.rb +4 -2
  210. data/lib/active_record/serialization.rb +2 -0
  211. data/lib/active_record/statement_cache.rb +63 -28
  212. data/lib/active_record/store.rb +121 -41
  213. data/lib/active_record/suppressor.rb +6 -3
  214. data/lib/active_record/table_metadata.rb +39 -18
  215. data/lib/active_record/tasks/database_tasks.rb +271 -81
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +243 -0
  221. data/lib/active_record/timestamp.rb +70 -36
  222. data/lib/active_record/touch_later.rb +8 -6
  223. data/lib/active_record/transactions.rb +141 -157
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  226. data/lib/active_record/type/date.rb +2 -0
  227. data/lib/active_record/type/date_time.rb +2 -0
  228. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  229. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  230. data/lib/active_record/type/internal/timezone.rb +2 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +16 -9
  233. data/lib/active_record/type/text.rb +11 -0
  234. data/lib/active_record/type/time.rb +12 -1
  235. data/lib/active_record/type/type_map.rb +14 -17
  236. data/lib/active_record/type/unsigned_integer.rb +16 -0
  237. data/lib/active_record/type.rb +23 -18
  238. data/lib/active_record/type_caster/connection.rb +17 -12
  239. data/lib/active_record/type_caster/map.rb +5 -4
  240. data/lib/active_record/type_caster.rb +4 -2
  241. data/lib/active_record/validations/absence.rb +2 -0
  242. data/lib/active_record/validations/associated.rb +3 -2
  243. data/lib/active_record/validations/length.rb +2 -0
  244. data/lib/active_record/validations/presence.rb +4 -2
  245. data/lib/active_record/validations/uniqueness.rb +29 -42
  246. data/lib/active_record/validations.rb +7 -5
  247. data/lib/active_record/version.rb +3 -1
  248. data/lib/active_record.rb +37 -22
  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 +256 -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 +203 -0
  315. data/lib/arel/visitors/dot.rb +296 -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 +156 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +158 -0
  321. data/lib/arel/visitors/oracle12.rb +65 -0
  322. data/lib/arel/visitors/postgresql.rb +109 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +888 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors/where_sql.rb +22 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +62 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  332. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  334. data/lib/rails/generators/active_record/migration.rb +17 -3
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record.rb +7 -5
  338. metadata +138 -52
  339. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  340. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  341. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  343. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  344. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  345. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  346. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  347. data/lib/active_record/attribute.rb +0 -213
  348. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  349. data/lib/active_record/attribute_set/builder.rb +0 -132
  350. data/lib/active_record/attribute_set.rb +0 -110
  351. data/lib/active_record/collection_cache_key.rb +0 -50
  352. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  353. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  354. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  355. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  356. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  357. data/lib/active_record/type/internal/abstract_json.rb +0 -33
  358. /data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  359. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,38 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module DatabaseStatements
5
7
  def explain(arel, binds = [])
6
8
  sql = "EXPLAIN #{to_sql(arel, binds)}"
7
- PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
8
- end
9
-
10
- def select_value(arel, name = nil, binds = [])
11
- arel, binds = binds_from_relation arel, binds
12
- sql = to_sql(arel, binds)
13
- execute_and_clear(sql, name, binds) do |result|
14
- result.getvalue(0, 0) if result.ntuples > 0 && result.nfields > 0
15
- end
16
- end
17
-
18
- def select_values(arel, name = nil, binds = [])
19
- arel, binds = binds_from_relation arel, binds
20
- sql = to_sql(arel, binds)
21
- execute_and_clear(sql, name, binds) do |result|
22
- if result.nfields > 0
23
- result.column_values(0)
24
- else
25
- []
26
- end
27
- end
28
- end
29
-
30
- # Executes a SELECT query and returns an array of rows. Each row is an
31
- # array of field values.
32
- def select_rows(sql, name = nil, binds = [])
33
- execute_and_clear(sql, name, binds) do |result|
34
- result.values
35
- end
9
+ PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", binds))
36
10
  end
37
11
 
38
12
  # The internal PostgreSQL identifier of the money data type.
@@ -74,9 +48,9 @@ module ActiveRecord
74
48
  # (2) $12.345.678,12
75
49
  case data
76
50
  when /^-?\D+[\d,]+\.\d{2}$/ # (1)
77
- data.gsub!(/[^-\d.]/, '')
51
+ data.gsub!(/[^-\d.]/, "")
78
52
  when /^-?\D+[\d.]+,\d{2}$/ # (2)
79
- data.gsub!(/[^-\d,]/, '').sub!(/,/, '.')
53
+ data.gsub!(/[^-\d,]/, "").sub!(/,/, ".")
80
54
  end
81
55
  end
82
56
  end
@@ -84,22 +58,43 @@ module ActiveRecord
84
58
 
85
59
  # Queries the database and returns the results in an Array-like object
86
60
  def query(sql, name = nil) #:nodoc:
61
+ materialize_transactions
62
+
87
63
  log(sql, name) do
88
- result_as_array @connection.async_exec(sql)
64
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
65
+ result_as_array @connection.async_exec(sql)
66
+ end
89
67
  end
90
68
  end
91
69
 
92
- # Executes an SQL statement, returning a PGresult object on success
93
- # or raising a PGError exception otherwise.
94
- # Note: the PGresult object is manually memory managed; if you don't
95
- # need it specifically, you many want consider the exec_query wrapper.
70
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
71
+ :close, :declare, :fetch, :move, :set, :show
72
+ ) # :nodoc:
73
+ private_constant :READ_QUERY
74
+
75
+ def write_query?(sql) # :nodoc:
76
+ !READ_QUERY.match?(sql)
77
+ end
78
+
79
+ # Executes an SQL statement, returning a PG::Result object on success
80
+ # or raising a PG::Error exception otherwise.
81
+ # Note: the PG::Result object is manually memory managed; if you don't
82
+ # need it specifically, you may want consider the <tt>exec_query</tt> wrapper.
96
83
  def execute(sql, name = nil)
84
+ if preventing_writes? && write_query?(sql)
85
+ raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
86
+ end
87
+
88
+ materialize_transactions
89
+
97
90
  log(sql, name) do
98
- @connection.async_exec(sql)
91
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
92
+ @connection.async_exec(sql)
93
+ end
99
94
  end
100
95
  end
101
96
 
102
- def exec_query(sql, name = 'SQL', binds = [], prepare: false)
97
+ def exec_query(sql, name = "SQL", binds = [], prepare: false)
103
98
  execute_and_clear(sql, name, binds, prepare: prepare) do |result|
104
99
  types = {}
105
100
  fields = result.fields
@@ -112,38 +107,41 @@ module ActiveRecord
112
107
  end
113
108
  end
114
109
 
115
- def exec_delete(sql, name = 'SQL', binds = [])
116
- execute_and_clear(sql, name, binds) {|result| result.cmd_tuples }
110
+ def exec_delete(sql, name = nil, binds = [])
111
+ execute_and_clear(sql, name, binds) { |result| result.cmd_tuples }
117
112
  end
118
113
  alias :exec_update :exec_delete
119
114
 
120
- def sql_for_insert(sql, pk, id_value, sequence_name, binds) # :nodoc:
115
+ def sql_for_insert(sql, pk, binds) # :nodoc:
121
116
  if pk.nil?
122
117
  # Extract the table from the insert sql. Yuck.
123
118
  table_ref = extract_table_ref_from_insert_sql(sql)
124
119
  pk = primary_key(table_ref) if table_ref
125
120
  end
126
121
 
127
- pk = suppress_composite_primary_key(pk)
128
-
129
- if pk && use_insert_returning?
122
+ if pk = suppress_composite_primary_key(pk)
130
123
  sql = "#{sql} RETURNING #{quote_column_name(pk)}"
131
124
  end
132
125
 
133
126
  super
134
127
  end
128
+ private :sql_for_insert
135
129
 
136
- def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
137
- val = exec_query(sql, name, binds)
138
- if !use_insert_returning? && pk
130
+ def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
131
+ if use_insert_returning? || pk == false
132
+ super
133
+ else
134
+ result = exec_query(sql, name, binds)
139
135
  unless sequence_name
140
136
  table_ref = extract_table_ref_from_insert_sql(sql)
141
- sequence_name = default_sequence_name(table_ref, pk)
142
- return val unless sequence_name
137
+ if table_ref
138
+ pk = primary_key(table_ref) if pk.nil?
139
+ pk = suppress_composite_primary_key(pk)
140
+ sequence_name = default_sequence_name(table_ref, pk)
141
+ end
142
+ return result unless sequence_name
143
143
  end
144
144
  last_insert_id_result(sequence_name)
145
- else
146
- val
147
145
  end
148
146
  end
149
147
 
@@ -168,10 +166,22 @@ module ActiveRecord
168
166
  end
169
167
 
170
168
  private
169
+ def execute_batch(statements, name = nil)
170
+ execute(combine_multi_statements(statements))
171
+ end
171
172
 
172
- def suppress_composite_primary_key(pk)
173
- pk unless pk.is_a?(Array)
174
- end
173
+ def build_truncate_statements(table_names)
174
+ ["TRUNCATE TABLE #{table_names.map(&method(:quote_table_name)).join(", ")}"]
175
+ end
176
+
177
+ # Returns the current ID of a table's sequence.
178
+ def last_insert_id_result(sequence_name)
179
+ exec_query("SELECT currval(#{quote(sequence_name)})", "SQL")
180
+ end
181
+
182
+ def suppress_composite_primary_key(pk)
183
+ pk unless pk.is_a?(Array)
184
+ end
175
185
  end
176
186
  end
177
187
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -26,12 +28,12 @@ module ActiveRecord
26
28
  pp = []
27
29
 
28
30
  pp << header.center(width).rstrip
29
- pp << '-' * width
31
+ pp << "-" * width
30
32
 
31
- pp += lines.map {|line| " #{line}"}
33
+ pp += lines.map { |line| " #{line}" }
32
34
 
33
35
  nrows = result.rows.length
34
- rows_label = nrows == 1 ? 'row' : 'rows'
36
+ rows_label = nrows == 1 ? "row" : "rows"
35
37
  pp << "(#{nrows} #{rows_label})"
36
38
 
37
39
  pp.join("\n") + "\n"
@@ -1,16 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
7
  class Array < Type::Value # :nodoc:
6
- include Type::Helpers::Mutable
8
+ include ActiveModel::Type::Helpers::Mutable
7
9
 
8
10
  Data = Struct.new(:encoder, :values) # :nodoc:
9
11
 
10
12
  attr_reader :subtype, :delimiter
11
- delegate :type, :user_input_in_time_zone, :limit, to: :subtype
13
+ delegate :type, :user_input_in_time_zone, :limit, :precision, :scale, to: :subtype
12
14
 
13
- def initialize(subtype, delimiter = ',')
15
+ def initialize(subtype, delimiter = ",")
14
16
  @subtype = subtype
15
17
  @delimiter = delimiter
16
18
 
@@ -31,7 +33,13 @@ module ActiveRecord
31
33
 
32
34
  def cast(value)
33
35
  if value.is_a?(::String)
34
- value = @pg_decoder.decode(value)
36
+ value = begin
37
+ @pg_decoder.decode(value)
38
+ rescue TypeError
39
+ # malformed array string is treated as [], will raise in PG 2.0 gem
40
+ # this keeps a consistent implementation
41
+ []
42
+ end
35
43
  end
36
44
  type_cast_array(value, :cast)
37
45
  end
@@ -64,15 +72,18 @@ module ActiveRecord
64
72
  deserialize(raw_old_value) != new_value
65
73
  end
66
74
 
67
- private
75
+ def force_equality?(value)
76
+ value.is_a?(::Array)
77
+ end
68
78
 
69
- def type_cast_array(value, method)
70
- if value.is_a?(::Array)
71
- value.map { |item| type_cast_array(item, method) }
72
- else
73
- @subtype.public_send(method, value)
79
+ private
80
+ def type_cast_array(value, method)
81
+ if value.is_a?(::Array)
82
+ value.map { |item| type_cast_array(item, method) }
83
+ else
84
+ @subtype.public_send(method, value)
85
+ end
74
86
  end
75
- end
76
87
  end
77
88
  end
78
89
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -34,16 +36,15 @@ module ActiveRecord
34
36
  end
35
37
 
36
38
  def binary?
37
- /\A[01]*\Z/ === value
39
+ /\A[01]*\Z/.match?(value)
38
40
  end
39
41
 
40
42
  def hex?
41
- /\A[0-9A-F]*\Z/i === value
43
+ /\A[0-9A-F]*\Z/i.match?(value)
42
44
  end
43
45
 
44
- protected
45
-
46
- attr_reader :value
46
+ private
47
+ attr_reader :value
47
48
  end
48
49
  end
49
50
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,4 +1,6 @@
1
- require 'ipaddr'
1
+ # frozen_string_literal: true
2
+
3
+ require "ipaddr"
2
4
 
3
5
  module ActiveRecord
4
6
  module ConnectionAdapters
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module PostgreSQL
6
+ module OID # :nodoc:
7
+ class Date < Type::Date # :nodoc:
8
+ def cast_value(value)
9
+ case value
10
+ when "infinity" then ::Float::INFINITY
11
+ when "-infinity" then -::Float::INFINITY
12
+ when / BC$/
13
+ astronomical_year = format("%04d", -value[/^\d+/].to_i + 1)
14
+ super(value.sub(/ BC$/, "").sub(/^\d+/, astronomical_year))
15
+ else
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -5,8 +7,8 @@ module ActiveRecord
5
7
  class DateTime < Type::DateTime # :nodoc:
6
8
  def cast_value(value)
7
9
  case value
8
- when 'infinity' then ::Float::INFINITY
9
- when '-infinity' then -::Float::INFINITY
10
+ when "infinity" then ::Float::INFINITY
11
+ when "-infinity" then -::Float::INFINITY
10
12
  when / BC$/
11
13
  astronomical_year = format("%04d", -value[/^\d+/].to_i + 1)
12
14
  super(value.sub(/ BC$/, "").sub(/^\d+/, astronomical_year))
@@ -14,6 +16,14 @@ module ActiveRecord
14
16
  super
15
17
  end
16
18
  end
19
+
20
+ def type_cast_for_schema(value)
21
+ case value
22
+ when ::Float::INFINITY then "::Float::INFINITY"
23
+ when -::Float::INFINITY then "-::Float::INFINITY"
24
+ else super
25
+ end
26
+ end
17
27
  end
18
28
  end
19
29
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
7
  class Decimal < Type::Decimal # :nodoc:
6
8
  def infinity(options = {})
7
- BigDecimal.new("Infinity") * (options[:negative] ? -1 : 1)
9
+ BigDecimal("Infinity") * (options[:negative] ? -1 : 1)
8
10
  end
9
11
  end
10
12
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -8,10 +10,9 @@ module ActiveRecord
8
10
  end
9
11
 
10
12
  private
11
-
12
- def cast_value(value)
13
- value.to_s
14
- end
13
+ def cast_value(value)
14
+ value.to_s
15
+ end
15
16
  end
16
17
  end
17
18
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
7
  class Hstore < Type::Value # :nodoc:
6
- include Type::Helpers::Mutable
8
+ include ActiveModel::Type::Helpers::Mutable
7
9
 
8
10
  def type
9
11
  :hstore
@@ -12,8 +14,8 @@ module ActiveRecord
12
14
  def deserialize(value)
13
15
  if value.is_a?(::String)
14
16
  ::Hash[value.scan(HstorePair).map { |k, v|
15
- v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
16
- k = k.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
17
+ v = v.upcase == "NULL" ? nil : v.gsub(/\A"(.*)"\Z/m, '\1').gsub(/\\(.)/, '\1')
18
+ k = k.gsub(/\A"(.*)"\Z/m, '\1').gsub(/\\(.)/, '\1')
17
19
  [k, v]
18
20
  }]
19
21
  else
@@ -23,7 +25,7 @@ module ActiveRecord
23
25
 
24
26
  def serialize(value)
25
27
  if value.is_a?(::Hash)
26
- value.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(', ')
28
+ value.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(", ")
27
29
  elsif value.respond_to?(:to_unsafe_h)
28
30
  serialize(value.to_unsafe_h)
29
31
  else
@@ -44,24 +46,23 @@ module ActiveRecord
44
46
  end
45
47
 
46
48
  private
49
+ HstorePair = begin
50
+ quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/
51
+ unquoted_string = /(?:\\.|[^\s,])[^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
52
+ /(#{quoted_string}|#{unquoted_string})\s*=>\s*(#{quoted_string}|#{unquoted_string})/
53
+ end
47
54
 
48
- HstorePair = begin
49
- quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/
50
- unquoted_string = /(?:\\.|[^\s,])[^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
51
- /(#{quoted_string}|#{unquoted_string})\s*=>\s*(#{quoted_string}|#{unquoted_string})/
52
- end
53
-
54
- def escape_hstore(value)
55
- if value.nil?
56
- 'NULL'
57
- else
58
- if value == ""
59
- '""'
55
+ def escape_hstore(value)
56
+ if value.nil?
57
+ "NULL"
60
58
  else
61
- '"%s"' % value.to_s.gsub(/(["\\])/, '\\\\\1')
59
+ if value == ""
60
+ '""'
61
+ else
62
+ '"%s"' % value.to_s.gsub(/(["\\])/, '\\\\\1')
63
+ end
62
64
  end
63
65
  end
64
- end
65
66
  end
66
67
  end
67
68
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -1,21 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
- class Jsonb < Json # :nodoc:
7
+ class Jsonb < Type::Json # :nodoc:
6
8
  def type
7
9
  :jsonb
8
10
  end
9
-
10
- def changed_in_place?(raw_old_value, new_value)
11
- # Postgres does not preserve insignificant whitespaces when
12
- # round-tripping jsonb columns. This causes some false positives for
13
- # the comparison here. Therefore, we need to parse and re-dump the
14
- # raw value here to ensure the insignificant whitespaces are
15
- # consistent with our encoder's output.
16
- raw_old_value = serialize(deserialize(raw_old_value))
17
- super(raw_old_value, new_value)
18
- end
19
11
  end
20
12
  end
21
13
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module PostgreSQL
6
+ module OID # :nodoc:
7
+ class LegacyPoint < Type::Value # :nodoc:
8
+ include ActiveModel::Type::Helpers::Mutable
9
+
10
+ def type
11
+ :point
12
+ end
13
+
14
+ def cast(value)
15
+ case value
16
+ when ::String
17
+ if value[0] == "(" && value[-1] == ")"
18
+ value = value[1...-1]
19
+ end
20
+ cast(value.split(","))
21
+ when ::Array
22
+ value.map { |v| Float(v) }
23
+ else
24
+ value
25
+ end
26
+ end
27
+
28
+ def serialize(value)
29
+ if value.is_a?(::Array)
30
+ "(#{number_for_point(value[0])},#{number_for_point(value[1])})"
31
+ else
32
+ super
33
+ end
34
+ end
35
+
36
+ private
37
+ def number_for_point(number)
38
+ number.to_s.gsub(/\.0$/, "")
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -22,12 +24,12 @@ module ActiveRecord
22
24
  # (3) -$2.55
23
25
  # (4) ($2.55)
24
26
 
25
- value.sub!(/^\((.+)\)$/, '-\1') # (4)
27
+ value = value.sub(/^\((.+)\)$/, '-\1') # (4)
26
28
  case value
27
- when /^-?\D+[\d,]+\.\d{2}$/ # (1)
28
- value.gsub!(/[^-\d.]/, '')
29
- when /^-?\D+[\d.]+,\d{2}$/ # (2)
30
- value.gsub!(/[^-\d,]/, '').sub!(/,/, '.')
29
+ when /^-?\D*+[\d,]+\.\d{2}$/ # (1)
30
+ value.gsub!(/[^-\d.]/, "")
31
+ when /^-?\D*+[\d.]+,\d{2}$/ # (2)
32
+ value.gsub!(/[^-\d,]/, "").sub!(/,/, ".")
31
33
  end
32
34
 
33
35
  super(value)
@@ -1,8 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
- class Json < Type::Internal::AbstractJson
7
+ class Oid < Type::UnsignedInteger # :nodoc:
8
+ def type
9
+ :oid
10
+ end
6
11
  end
7
12
  end
8
13
  end
@@ -1,9 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
4
+ Point = Struct.new(:x, :y)
5
+
2
6
  module ConnectionAdapters
3
7
  module PostgreSQL
4
8
  module OID # :nodoc:
5
9
  class Point < Type::Value # :nodoc:
6
- include Type::Helpers::Mutable
10
+ include ActiveModel::Type::Helpers::Mutable
7
11
 
8
12
  def type
9
13
  :point
@@ -12,30 +16,47 @@ module ActiveRecord
12
16
  def cast(value)
13
17
  case value
14
18
  when ::String
15
- if value[0] == '(' && value[-1] == ')'
19
+ return if value.blank?
20
+
21
+ if value[0] == "(" && value[-1] == ")"
16
22
  value = value[1...-1]
17
23
  end
18
- cast(value.split(','))
24
+ x, y = value.split(",")
25
+ build_point(x, y)
19
26
  when ::Array
20
- value.map { |v| Float(v) }
27
+ build_point(*value)
21
28
  else
22
29
  value
23
30
  end
24
31
  end
25
32
 
26
33
  def serialize(value)
27
- if value.is_a?(::Array)
28
- "(#{number_for_point(value[0])},#{number_for_point(value[1])})"
34
+ case value
35
+ when ActiveRecord::Point
36
+ "(#{number_for_point(value.x)},#{number_for_point(value.y)})"
37
+ when ::Array
38
+ serialize(build_point(*value))
39
+ else
40
+ super
41
+ end
42
+ end
43
+
44
+ def type_cast_for_schema(value)
45
+ if ActiveRecord::Point === value
46
+ [value.x, value.y]
29
47
  else
30
48
  super
31
49
  end
32
50
  end
33
51
 
34
52
  private
53
+ def number_for_point(number)
54
+ number.to_s.gsub(/\.0$/, "")
55
+ end
35
56
 
36
- def number_for_point(number)
37
- number.to_s.gsub(/\.0$/, '')
38
- end
57
+ def build_point(x, y)
58
+ ActiveRecord::Point.new(Float(x), Float(y))
59
+ end
39
60
  end
40
61
  end
41
62
  end