One important thing to keep in mind is that Record objects lazy-load and cache related records. That is to say that, when getAddressRecord() was called, behind the scenes, a new record object was created, populated and stored in the variables scope of the CustomerRecord.
That means that if you call this method twice while, betwixt the first and second call, someone else updates the Address, the data in your second call will not contain the changes made by the other person.
In fact, all objects that do not contain mutable (changable) instance data are cached by the framework and become singletons within one instance of the ReactorFactory.
Additionally, when you call save on a record with relationships to other records the save will cascade down to related objects which are either new or have been modified. For example, a customer hasOne address. When you save the customer the customer's address will also be saved if it's been modified. In Reactor's vocabulary records which have been modified are said to be "dirty".
Deletes do not cascade. If you attempt to delete something which violates a foreign key constraint you will receive an error.
Let's take a look at cascading saves. Here's some code which will create a new Customer and Address. Note that to save both the user and the address I only call save on the Customer:
<!--- create the reactorFactory --->
<cfset Reactor = CreateObject("Component", "reactor.reactorFactory").init(expandPath("reactor.xml"))
/>
<!--- create a customerRecord --->
<cfset CustomerRecord = Reactor.createRecord("Customer") />
<!--- get the user record's address --->
<cfset AddressRecord = CustomerRecord.getAddress() />
<!--- populate the customer and address --->
<cfset CustomerRecord.setUsername("jblow") />
<cfset CustomerRecord.setPassword("9ummy") />
<cfset CustomerRecord.setFirstName("Joe") />
<cfset CustomerRecord.setLastName("Blow") />
<cfset AddressRecord.setStreet1("1234 Left Turn Ln.") />
<cfset AddressRecord.setCity("Albuquerque") />
<cfset AddressRecord.setState("New Mexico") />
<cfset AddressRecord.setZip("87112") />
<!--- save the customer and address! --->
<cfset CustomerRecord.save() />
<!--- create the reactorFactory --->
<cfset Reactor = CreateObject("Component", "reactor.reactorFactory").init(expandPath("reactor.xml"))
/>
<!--- create a customerRecord --->
<cfset CustomerRecord = Reactor.createRecord("Customer").load(customerId=2)
/>
<!--- update the customer's address --->
<cfset CustomerRecord.getAddress().setStreet1("432 Foo Ln.")
/>
<cfset CustomerRecord.getAddress().setCity("Dead Horse") />
<cfset CustomerRecord.getAddress().setState("Alaska") />
<cfset CustomerRecord.getAddress().setZip("99723") />
<!--- save the changes--->
<cfset CustomerRecord.save() />
Pop Quiz: How many
queries were run in the last block of code?
Answer: Three. One to load the CustomerRecord when load()
is called. One
to load the Address when getAddress() is first
called (Reactor lazy-loads the AddressRecord and caches it in the CustomerRecord).
One to save the Address when save() is called
on the CustomerRecord. The
customer is not saved because it's not dirty.