Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UUID column value not available until a model reload

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?

like image 737
David Tuite Avatar asked Aug 23 '14 17:08

David Tuite


2 Answers

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?

like image 174
steve Avatar answered Sep 20 '22 03:09

steve


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.

like image 33
King'ori Maina Avatar answered Sep 20 '22 03:09

King'ori Maina