5

Is there a way to get embedded documents to initialize automatically on construction in mongoid? What I mean is given that User which embeds a garage document. I have to write the following code to fully set up the user with the garage:

user = User.create!(name: "John")
user.build_garage
user.garage.cars << Car.create!(name: "Bessy")

Is there a way I can skip calling user.build_garage?

Thanks

GTDev
  • 5,488
  • 9
  • 49
  • 84

2 Answers2

12

Mongoid 3 have autobuild option which tells Mongoid to instantiate a new document when the relation is accessed and it is nil.

embeds_one :label, autobuild: true
has_one :producer, autobuild: true
jpalumickas
  • 720
  • 7
  • 6
6

You can add a callback to the User model like this:

class User
  ...
  after_initialize do |u|
    u.build_garage unless u.garage
  end
  ...
end

This callback fires after each instantiation of the class, so it fires after 'find' and 'new'.

moritz
  • 25,477
  • 3
  • 41
  • 36
  • Is firing after find a good idea because doesn't that mean it will overwrite the previous embedded document? – GTDev Nov 10 '11 at 04:15
  • Are there any mongoid autos that do this for the user? – GTDev Nov 10 '11 at 05:03
  • I edited the answer to fix your first point. No, there are no automatisms for that. I would say that such functionality belongs to the actual application code. – moritz Nov 10 '11 at 07:52
  • Dude. You rock! I was trying to use the initialize method to do this. Even though I was calling super first, the condition was failing and adding an extra doc. I'd add that maybe you should add a garage.exists? to that unless – Chance Dec 04 '12 at 14:44
  • Mongoid 3 now has an option for this, [autobuild](https://github.com/mongoid/mongoid/pull/1188) – Yeggeps Apr 19 '13 at 09:34