Doug, the event model seems very nice and I need to study this iterator thing.
BTW, what do you think about the "<cfproperty />" inside the reactor for each db field? I ask this because it doesn't seem to harm reactor and we could be able to map our Record Objects to AS3 classes. As usual, a great job (each time better)! João Fernandes -----Original Message----- From: [EMAIL PROTECTED] on behalf of Doug Hughes Sent: Fri 17-Feb-06 9:05 PM To: [email protected] Subject: Reactor For CF Big update 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 ColdFusion Mailing List -- [email protected] -- Archives at http://www.mail-archive.com/reactor%40doughughes.net/ -- Reactor for ColdFusion Mailing List -- [email protected] -- Archives at http://www.mail-archive.com/reactor%40doughughes.net/
<<winmail.dat>>

