|
Hey all, This email is being sent to let you know that I’ve committed
a significant new update to Reactor. This addresses a number of issues I’ve
seen with reactor and should help improve things. However, if you use
many to many relationships (and who doesn’t?) you’re going to need
to do more than just get the latest reactor. Here’s what’s new: When you have a manyToMany relationship in your app reactor
no longer generates the createXyzQuery(), getXyzQuery(), and getXyzArray()
methods. Instead, it generates one method, getZyzIterator(). This returns
an Iterator object that encapsulates a Query object. The Iterator has a
few important methods. First off, getQuery() and getArray(). These are
the same as getXyzQuery(), and getXyzArray() previously. However, there
are also methods that provide access to the OO query behind the scenes.
You can call getwhere() to add filters directly to the Iterator, getOrder() to
set the sorting of the data (in both the query and arrays you can get from
this). Lastly there’s hasMore() and next() which can be used to
loop over elements in the Iterator (hence the name). Also, when you call getXyzRecord or Iterator the Record will
cache the results into an instance variable. This might lead to concurrency
issues if you store your record in a persistence scope (and other
situations). However, it really made the most sense, in my opinion. The Docs and samples have been updated to reflect these two
changes. However, there’s another big change that’s not been
documented, an event model. Let’s say that you have a UserRecord and it hasOne
AddressRecord via an addressId column. Traditionally, if you wanted to
create a new User and save it you’d have to: 1) Create a
userRecord 2) Populate the
userRecord 3) Get/Create
the addressRecord 4) Populate the
addressRecord 5) Save the
addressRecord 6) Set the
addressRecord into the userRecord 7) Save the
userRecord Now, this is already a pain, but what if you wanted to
validate the user and address before saving it? Well, that’s more
complicated. However, you can now use the event model to simplify this a
bit. There are eight events by default on every record:
beforeValidate, afterValidate, beforeSave, afterSave, beforeLoad, afterLoad,
beforeDelete, afterDelete. You can tell a record to notify another record
in the case that a particular event occurs. To start out simple, let’s say we wanted to validate
the address at the same time we validate the user. Well, to do this you’d
need to add a custom method to your Address record that accepts a
Reactor.event.event object as an argument. You can call it whatever you
want, but let’s use handleValidate() as an example. You can have
the address listen for the afterValidate event like this: <cfset userRecord.attachDelegate(“afterValidate”,
addressRecord, “handleValidate”) /> Now, when you call userRecord.validate() the
handleValidate() method on the addressRecord will be executed and will receive an
event object. The event object contains the name of the event, the source
of the event (incase you’re listening on more than one record), and optional
metadata. In the case of the afterValidate event, the
validaionErrorCollection object is passed along. You can get it using
some code in your handleEvent method like this: <cfset var Errors = arguments.event.getValue(“validationErrorCollection”)
/> This is actually rather similar to what Joe does with events
in model-glue. You could then call the address object’s validate
method and pass in that error collection. If errors are added they’ll
all end up in the collection returned by the user’s validate method. So, that’s nice. But what if you wanted to save the
address before the user is saved and what if you wanted to set the user’s
addressId automatically? Well, you could add a method to listen for the
beforeSave event on the user. Because this contains the source of the
event, you could save the address and then call the soruce’s
setAddressId() method. Here’s an example of such a method: <!--- handleSave ---> <cffunction name="handleSave"
access="public" output="false"
returntype="void"> <cfargument
name="Event" hint="I am the event object."
required="yes" type="reactor.event.event" /> <!---
save this address ---> <cfset
save() /> <!---
set the addressId on the source user ---> <cfset
arguments.event.getSource().setAddressId(getAddressId()) /> </cffunction> Here’s what you’d use to make this method listen
for the event: <cfset userRecord.attachDelegate(“beforeSave”,
addressRecord, “handleSave”) /> There’s a lot more to this, but I’m going to get
into it. Check out the abstractRecord and the reactor.event.event object
and you’ll see where I’m headed. As time permits I’ll
actually document it. Lastly, there’s a new zip on doughughes.net which is
the same as the current revision in subversion. Doug |
- Reactor For CF Big update Doug Hughes
- RE: Reactor For CF Big update João Fernandes
- RE: Reactor For CF Big update Doug Hughes
- Re: Reactor For CF Big update Jared Rypka-Hauer
- Re: Reactor For CF Big update Sean Corfield
- Re: Reactor For CF Big update Sean Corfield
- Re: Reactor For CF Big update Jared Rypka-Hauer
- Re: Reactor For CF Big update Sean Corfield
- RE: Reactor For CF Big update Doug Hughes

