ActiveRecord - How to associate (unsaved) child of (unsaved) parent with another object before saving all objects

225 views Asked by At

i'm relatively new to Rails and Ruby and run into the following question.

I have a 3 objects:

  1. Parent object called Partner

    • Has many Tariffs
  2. object called Tariff
    • Belongs to Partner
  3. a 3rd object what has a has one relation with the child object called User
    • Belongs to Tariff

When i create a new Partner (partner = Partner.new) and a new tariff (tariff = Tariff.new) and add the tariff to the partner (Partner.tariffs << tariff) i'm able to save the Partner with it relation by doing partner.save!.

But in my situation i also get a user from the database (user = User.find.last) and want to directly add the association with the tariff before i save everything to the database. This because i want to save/update everything in 1 transaction so everything will be role backed in case of an error.

I tried many ways to achieve this but i cant get it done. I thought it would be something like this:

partner = Partner.new
tariff = Tariff.new
partner.tariffs << tariff
user = User.find.last
user.tariff = tariff

ActiveRecord::Base.transaction.do
  partner.save!
  user.save!
end

or

partner = Partner.new
tariff = Tariff.new
partner.tariffs << tariff
user = User.find.last
user.tariff = tariff

ActiveRecord::Base.transaction.do
  partner.save!
  user.save!
end

or

partner = Partner.new
tariff = Tariff.new
partner.tariffs << tariff
user = User.find.last
user.tariff_id = tariff.id (or something similar) 

ActiveRecord::Base.transaction.do
  partner.save!
  user.save!
end

I understand that some of my cases/examples cant work as there is no tariff.id and there is no partner.tariff.last as long as the objects are not saved to the database.

It would be nice if someone can help me out, thanks in advance!

1

There are 1 answers

0
CodeNinja On

I solved my problem like this:

partner = Partner.new
tariff = Tariff.new
partner.tariffs << tariff

ActiveRecord::Base.transaction.do
  partner.save!
  user.update_attributes(:tariff_id => tariff.id)
end

This works because the tariff object has an idea after the save method is called. The tariff is also saved when the partner is saved as the child is an new object and first level child of the partner. Unfortunately children of the child are not saved automatically.