3

Say we have the models Patient and PatientRawData (with a belongs_to association to Patient).

Is it possible to create new records (without saving them in database), associate them, and finally save them in the database?

Something like this:

patient = Patient.new(:name => 'John', :age => 34)
rawtext = PatientRawText.new(:rawtext => 'My name is..')
patient.rawtext = rawtext
patient.save!

The reason I want to do this, is that in my real case scenario there might more complex models/associations and I would prefer to not have partial things in the database in case of an exception.

For this reason I prefer to build whatever complex thing I want, and as a final step to store the whole thing in the database.

4 Answers 4

2

Rails have out of the box support for this type of issues using nested attributes. http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

class Patient < ActiveRecord::Base
  has_one :patient_raw_text
  accepts_nested_attributes_for :patient_raw_text
end

params = { patient: { name: 'Jack', patient_raw_text_attributes: { rawtext: '...' } }}
member = Patient .create(params[:patient])
Sign up to request clarification or add additional context in comments.

Comments

2

You can use transaction to prevent a bunch of records being created. It will roll back all ActiveRecord saves if an exception occurs anywhere in the block.

ActiveRecord::Base.transaction do
  patient = Patient.new(:name => 'John', :age => 34)
  rawtext = PatientRawText.create!(:rawtext => 'My name is..')
  patient.rawtext = rawtext
  patient.save! # <- if this fails
  raise "I don't want to be here"  # <- or if you manually raise an exeption 
end

If an exception is raised, even after the PatientRawText object was successfully created (say if patient.save! fails) then the PatientRawText creation will be rolled back.

Comments

1

Using new on the instance's reference will create an unsaved associated model whose foreign key will be automatically assigned when the parent is saved. In other words...

patient = Patient.new(:name => 'John', :age => 34)
patient.patient_raw_text.new(:rawtext => 'My name is..')
patient.save!

It's the same as you suggested...just saves a line and local variable assignment

Comments

-1

Yes, Rails allows we do that:

patient = Patient.new(:name => 'John', :age => 34)
patient.build_patient_raw_text(:rawtext => 'My name is..')
patient.save!

1 Comment

This method doesn't exist.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.