Posted by Russ Johnson in
Coldbox
on November 16, 2007 | 20 responses
Since I have made the switch to using ColdBox, I never get tired of discovering features that are already built into the framework. I find myself so caught up in the framework "just working" that I sometimes forget to look into all of the plugins for features that I could really take advantage of. Luis calls ColdBox "A next generation Framework and Development Toolkit" and I really keep forgetting about the development toolkit part. There are so many built-in tools to help you out with your application that its almost dizzying.
One such plugin that I have found myself using quite often lately is the BeanFactory plugin. This plugin makes working with Transfer extremely easy by automatically populating new beans with data for you among other things. Im not going to go into full detail but I wanted to show an example of populating an empty Transfer object with data and saving that Transfer object back to the database.I have a form that accepts user data to allow users to register with the site. Whats in this form is not really relevant at this point, we just need to know that when we submit the form, its data is put into the request collection or RC scope for us by ColdBox and that the form is submitted to an event named User.doAddUser. Lets take a look at the code for the doAddUser method in the User event handler that will be saving our form data.
<cffunction name="doAddUser" access="public" returntype="void" output="false">
<cfargument name="Event" type="coldbox.system.beans.requestContext">
<cfset var rc = event.getCollection()>
<cfset var oUser = "">
<cfset oUser = rc.Transfer.new("users.user")>
<cfset getPlugin("beanFactory").populateBean(oUser)>
<cfset rc.Transfer.save(oUser)>
<cfset getPlugin("messagebox").setMessage("info", "You have successfully created a new user.")>
<cfset setNextEvent("User.dspUsers")>
</cffunction>
Now lets break this code down further and see just whats going on here. Im not going to cover the standard ColdBox code, that stuff has been covered in
other posts on my blog. Instead we will focus on the bits that get the work done.
The first line here grabs the event collection and sticks it into the rc scope for easy reference. This isnt entirely necessary as there are other ways of doing it but this is the easier and has almost become a convention among ColdBox users.
<cfset var rc = event.getCollection()/>
The next couple of lines create a local variable and assign it to a new empty Transfer object of the users type from our trasfer config.
<cfset var oUser = "">
<cfset oUser = rc.Transfer.new("users.user")/>
Now the magic happens! We make a simple call to the beanFactory plugin and call the populateBean method and pass in our empty Transfer object. The beanFactory will take the form data out of the RC scope and use it to populate the Transfer object automagically.
<cfset getPlugin("beanFactory").populateBean(oUser)>
Then we simply call the save method of our Transfer object and pass our newly populated bean as an argument.
<cfset rc.Transfer.save(oUser)>
Lastly, we use another one of ColdBox's nifty tools and call the MessageBox plugin to return a nice success message to our next event and then relocate the request to the dspUsers method to display our list.
<cfset getPlugin("messagebox").setMessage("info", "You have successfully created a new user.")>
<cfset setNextEvent("User.dspUsers")>
Thats all there is to it. Thats one of the things that sets ColdBox apart form some of the other ColdFusion frameworks in my opinion. Its not only geared toward helping you build more elegant applications but also to make that process easier with its toolset.
Or does the automagic stuff happen only when naming conventions are strictly adhered to. I am recently getting into OOP so this is very fascinating to me.
I always make sure my form field names and transfer object properties match. Its a habit that I got into long ago making sure that formfield names and db column names matched. Just seems to make things easier.
I think it might be time to break that habit.
At the moment beanfactory only mapps to form-fields and form-field should be in the name of bean mehtods. In future we will have property support and property based validation rules. at the moment its just ideas but we will see what will come-out.
I would recmend to use Brian, cfc generator then you would not worry about the bean methods naming issue.
@Russ I glad you really like the beanfactory... excellent post on power of coldbox. I hope you are enjoying coldbox development.
Model-Glue and Mach-ii both do this as well, but it's not oft promoted. In Model-Glue, it's arguments.event.makeEventBean(foo).
-Joe
Sorry, I coudn't resist....
What else does the "bean factory" do? It seems a very strange name for a utility that just loops over the event object (Fusebox, Mach-II, Model-Glue), er... oh that's right, ColdBox calls it a request collection... and simply calls setXxx() on the bean for each thing it finds there.
I'm all for choice in frameworks but I find the almost religious enthusiasm for ColdBox a little odd, especially when it is being praised for things that other frameworks have being doing for a while. Mind you, Luis is the only framework author I know who on his "bio" slide has "Christian" as one of his credentials... :)
MVC frameworks all do the same job really. They're all trying to solve the same set of problems - more or less. They're all evolving. Each new release of each framework tends to leapfrog over other frameworks in one way or another and then the advantage goes the other way pretty quickly.
All that said, it's good to see blog posts highlighting features of each framework as it all helps people make informed choices about which framework to use. The enthusiasm around ColdBox now is very much like the enthusiasm around Model-Glue 1.0 when it came out (and again around Model-Glue 2.0 when that came out - and, I suspect, that we'll see around Model-Glue 3.0 when that comes out too). And we'll see it around Mach-II 2.0 I expect. Fusebox 5.5 is getting a lot of love too I guess but it's been around so long and is so popular that it just doesn't get the fervor these days :)
I dont see any crazy fanaticism around ColdBox, anymore than I thought there was all these years when people like myself and others were singing the praises of Fusebox. I have just found a way to develop my applications that is "better for me". And I like to share that enthusiasm with others, the same way Joe posts about features of Model-Glue or you post about Fusebox.
Question: why use 2 lines and not just one:
<cfset var oUser = rc.Transfer.new("users.user")/>
I immediately recognized the parallel between CB's beanFactory populatebean method and MG's makeEventBean. What's cool about Coldbox is that Luis has made it so easy to extend the framework to your liking. For example, I was able to emulate Model Glue's viewstate.getValue("myself") functionality (great for dynamically setting links in your views) by coding a request context decorator in Coldbox that gave me the same result. I posted this in Luis's forum:
http://www.luismajano.com/forums/index.cfm?event=ehMessages.dspMessages&threadid=ED2D8303-FF65-CEF6-65BE18695C3BF0DC
I find I cannot use PopulateBean() because the setter for the field with the foreign key (e.g. orderItems:orderId) expects an instantiated bean of the type 'order'. The request scope however does not contain a bean for that field (usuallky a numeric value) so Transfer errors out with a message to that effect.
Do you know if ther's a way around this - short of manualley updating the 'simple' fields, creating a bean for the order and passing that as an argument to the setOrderId() function?
Marc
I am converting site from model-glue to coldbox.But I am facing problem in coldbox with request variables..which I could access properly in modelglue but not in coldbox.
Can anyone help me with this?
I am using setnextevent to jump from event .
I tried persist method with setnextevent but that didnt help me :(
"How do I access request variables in coldbox?"
"Do you know any simple method to convert application from modelgle to coldbox?"