I have a model with a :uuid
column set up by the following migration.
add_column :website, :uuid, :uuid, default: "uuid_generate_v4()"
It seems that the UUID isn't generated until I reload a newly created website.
website = Website.create!(host: 'example.com')
website.uuid
# => nil
website.reload
# => "de76e1c0-ac4a-4da6-8baf-8b9f037d39b1"
Is there a way to make the UUID available without having to reload?
I also stumbled on this. Found this closed issue in Rails, maintainers basically saying "this is intended" (great, thanks).
I ended up using something similar to the workaround described near the bottom, here's my snippet:
after_commit :reload_uuid, on: :create
def reload_uuid
self[:uuid] = self.class.where(id: id).pluck(:uuid).first
end
I don't bother checking if it has a uuid attribute because I only add this to my classes with uuid's and I use after_commit
because why bother getting the uuid if some other callback causes the save to fail?
I'd say, 'not that I know of' ... so. No.
Only way to avoid this is not delegate UUID generation to the DB via uuid_generate_v4()
and generate it on Ruby/Rails side using something like SecureRandom.uuid
. A callback like before_save
would do.
I guess it was a design decision on ActiveModel not to reload after save for performance reasons. I mean, you could do it if you want to, but not assume that's the case for all scenarios (from their POV) ... so ActiveModel just returns the object that it last had to avoid the trip to the DB.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With