Guest User

Untitled

a guest
Aug 3rd, 2020
35
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ### Steps to reproduce
  2.  
  3. **1. Create a model**
  4.  
  5. ```Ruby
  6. class Order < ApplicationRecord
  7. end
  8. ```
  9.  
  10. **2. Create a migration with a DB function as `default`.**
  11.  
  12. ```Ruby
  13. class CreateOrders < ActiveRecord::Migration[5.2]
  14. def change
  15. create_table :orders do |t|
  16. t.string :uuid, default: -> { "gen_random_uuid()" }
  17. t.references :user
  18. t.references :product
  19. t.text :comment
  20.  
  21. t.timestamps
  22. end
  23. end
  24. end
  25. ```
  26.  
  27. `rails db:migrate`
  28.  
  29. **3. Create a new order**
  30.  
  31. `rails console`
  32.  
  33. ```
  34. order = Order.create(user_id: 1, product_id: 1)
  35. ```
  36.  
  37. ### Expected behavior
  38. I expect `create` to set `uuid` (by the postgres default) **and** for it to set the new `uuid` value into the `order` AR instance, as it does with the `id`.
  39.  
  40. ```
  41. > order
  42. # =>
  43. # +----+--------------------------------------+---------+------------+---------+----------------+----------------+
  44. # | id | uuid | user_id | product_id | comment | created_at | updated_at |
  45. # +----+--------------------------------------+---------+------------+---------+----------------+----------------+
  46. # | 1 | bec94fe0-f7c3-4ede-8b25-c4bce702ec00 | 1 | 1 | | 2018-10-17 ... | 2018-10-17 ... |
  47. # +----+--------------------------------------+---------+------------+---------+----------------+----------------+
  48. ```
  49.  
  50. ### Actual behavior
  51. The `uuid` does get set in the db, but it is not returned into the `order` instance.
  52.  
  53. ```
  54. > order
  55. # =>
  56. # +----+------+---------+------------+---------+----------------+----------------+
  57. # | id | uuid | user_id | product_id | comment | created_at | updated_at |
  58. # +----+------+---------+------------+---------+----------------+----------------+
  59. # | 1 | | 1 | 1 | | 2018-10-17 ... | 2018-10-17 ... |
  60. # +----+------+---------+------------+---------+----------------+----------------+
  61. ```
  62.  
  63. ### Current workaround
  64.  
  65. Calling `order.reload` does then retrieve the values set by postgres. Other workarounds are [described in this issue](https://github.com/rails/rails/issues/21627)
  66.  
  67. ```
  68. > order
  69. # =>
  70. # +----+--------------------------------------+---------+------------+---------+----------------+----------------+
  71. # | id | uuid | user_id | product_id | comment | created_at | updated_at |
  72. # +----+--------------------------------------+---------+------------+---------+----------------+----------------+
  73. # | 1 | bec94fe0-f7c3-4ede-8b25-c4bce702ec00 | 1 | 1 | | 2018-10-17 ... | 2018-10-17 ... |
  74. # +----+--------------------------------------+---------+------------+---------+----------------+----------------+
  75. ```
  76.  
  77. ### Background
  78.  
  79. [This issue already describes](https://github.com/rails/rails/issues/21627) this bug, but the issue was initially a request to support functional defaults, which has since been implemented.
  80.  
  81. This quote from the discussion summarizes it pretty well:
  82.  
  83. > @kenaniah Sure, but it makes sense why the full row shouldn't be returned by default: there could be too much data, and ActiveRecord already knows both default and non-default values. (Or at least it thinks so.) But if the default value is generated by a function in PG then ActiveRecord doesn't know. Turns out that is not enough reason to make `RETURNING *` the default, and I'm ok with that. I think what we need is another parameter to tell ActiveRecord, that for a particular model, it should use `RETURNING *` instead.
  84.  
  85. This blog post [describes the issue wonderfully](https://www.devmynd.com/blog/db-generated-values-and-activerecord/).
  86.  
  87. ### Next steps
  88.  
  89. So a solution could be an option to tell AR to use `RETURNING *` in some instances. But I myself am not familiar with the ActiveRecord internals so I feel this should be further discussed.
  90.  
  91. ### System configuration
  92. **Rails version**: 5.2.1
  93.  
  94. **Ruby version**: 2.4.1
  95.  
  96. **Postgres version**: 9.6.3
RAW Paste Data