Its Magic! The ColdBox BeanFactory Plugin

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 = "">
<!--- get a new transfer object --->
<cfset oUser = rc.Transfer.new("users.user")>
<!--- now populate the transfer object with the form data --->
<cfset getPlugin("beanFactory").populateBean(oUser)>
<!--- finally we save our transfer object to the database --->
<cfset rc.Transfer.save(oUser)>
<cfset getPlugin("messagebox").setMessage("info", "You have successfully created a new user.")>
<!--- relocate to the list page --->
<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.


Feel free to Leave a Comment or just read what others have to say

17 Comments (Comment Moderation is enabled. Your comment will not appear until approved.) so far

  1. Ben Nadel 11/16/07 6:16 PM
    Ben Nadel's Gravatar I haven't used ColdBox, so sorry if this is a totally ignorant question, but how does the BeanFactory know how to map the form fields to the bean properties? For instance, if I had a bean that had a StartDate property, but my form had a StartDate and StartTime property, can you tell it to combine those two values during the mapping?

    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.
  2. Russ Johnson 11/16/07 6:33 PM
    Russ Johnson's Gravatar Hey Ben! The mappings are handled by name. So the form field "fName" would be put into the "fName" property of the bean. It does not provide a way of mapping the form fields to the properties. To use a WAY overused phrase, it favors convention over configuration. As much as that pains me to say that.

    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.
  3. Ben Nadel 11/16/07 6:43 PM
    Ben Nadel's Gravatar That's cool. My DB names and form field names have always matched up (ex. first_name). But, then when I started playing around with CFCs and OOP, my property names were all camel case (ex. FirstName). This has always been a discrepency with me; form / url fields used under scores and CF-side names were camel case. Not sure why I do it, but the habit clearly doesn't allow for any automation.

    I think it might be time to break that habit.
  4. Sana 11/16/07 6:58 PM
    Sana's Gravatar Hey Ben,
    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.
  5. Russ Johnson 11/16/07 7:06 PM
    Russ Johnson's Gravatar @Ben, Well if you are using Transfer then that can be used as your mapper. You can name your columns one thing and your formfields something else but in the transfer config, you assign a "name" property that matches the name used in the formfield. An alias basically.
  6. Ben Nadel 11/16/07 7:13 PM
    Ben Nadel's Gravatar I gotcha, sort of... I understand what you are saying, I just haven't used these frameworks and utilities yet.
  7. Joe Rinehart 11/16/07 7:35 PM
    Joe Rinehart's Gravatar Hi all,

    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
  8. Russ Johnson 11/16/07 7:46 PM
    Russ Johnson's Gravatar @Joe, How dare you speak of the frameworks of which I dare not speak their name!! LOL

    Sorry, I coudn't resist....
  9. Sean Corfield 11/17/07 12:56 AM
    Sean Corfield's Gravatar My first thought reading this was "So? Mach-II and Model-Glue have done this for ages..." then I noticed Joe had already popped in and pointed that out.

    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 :)
  10. Russ Johnson 11/17/07 1:41 AM
    Russ Johnson's Gravatar @ Sean, One thing you have to keep in mind is that a lot of people who are out there reading these blogs have never used any other frameworks, or any framework at all for that matter. These posts are not to inform or persuade Mach-ii or Model-Glue poeple from their framework over to ColdBox. Its merely sharing a discovery of a cool / helpful feature for those that may be using ColdBox or have been thinking about trying it out. Folks like Ben Nadel from the first comment who is just getting into this style of coding.

    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.
  11. ziggy 11/17/07 4:16 AM
    ziggy's Gravatar The last comment seems pretty accurate. I haven't used a framework and have been looking at coldbox, so I like posts like these. (I also don't mind being told other frameworks do it to, and how they might differ, just not in a crabby way.)

    Question: why use 2 lines and not just one:

    <cfset var oUser = rc.Transfer.new("users.user")/>
  12. Russ Johnson 11/17/07 9:48 AM
    Russ Johnson's Gravatar @ziggy, you of course could do that. I used two lines to help demonstrate the processes anf make it a little more verbose. But your way would work.
  13. Tony Garcia 11/19/07 10:18 PM
    Tony Garcia's Gravatar The first framework I looked at was Model-Glue, which I thought was the best thing since sliced bread. But then when I checked out Coldbox, it totally won me over. Nothing against M-G -- I still think it's a great framework. But, like Russ, I found Coldbox to be "better for me."
    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=e...
  14. Praveen 12/3/07 2:35 PM
    Praveen's Gravatar any tutorial on how to integrate Transfer with ColdBox. i am new to coldbox as well as transfer
  15. Russ Johnson 12/3/07 2:38 PM
    Russ Johnson's Gravatar Havent really thought about that, but that sounds like a great idea for a post. I will start working on that later today. I will see if I can get something up this week.
  16. Praveen 12/3/07 3:00 PM
    Praveen's Gravatar Thanks a bunch.. i have digged thru coldbox and seen transfer preso so few hints will suffice for me. I am assuming you had to write some code in Application.cfc to make it available to your request context.
  17. Russ Johnson 12/3/07 4:30 PM
    Russ Johnson's Gravatar If you have the ColdBox code downloaded, look through the sample code for the Transfer Sample application. It shows exactly how to set Transfer up with ColdBox. Its dead simple.