Monday, 28 June 2010

Reasons to hate Silverlight Part I

Looking back now, I nearly fell for it, I feel so stupid but I am glad that my natural underlying cynicism of all things new and shinny let me look at this emerging Microsoft technology with an impartial mind.  The marketing that came out of Microsoft was truly outlandish. I do of course talk about Silverlight which is the latest evil incarnation of that festering sore on the landscape of web development known as the browser plugin.  I have hated flash from an end user point of view for a long time, this was further intensified when I worked for a web agency which meant lots of interaction with this island of proprietary insanity that sits menacingly in prominent areas of public facing websites.


Looking back now, the hysteria and hype that greeted the build up and subsequent launch of silverlight was completely over the top.  It was flaunted as a game changer which was the future of the web.   Funny how they flaunted a flash clone as original and ground breaking but originality is not something Microsoft is renowned for. JavaScript and CSS were nothing more than short term hacks that were keeping the ubiquitous seat warm until Silverlight was ready for market.  I debated this on the once popular ALT.NET forum in this thread some time ago, were I was told by developers that this was the future.  The most hilarious argument I got was that "I would be left be behind", if I did not open my arms and embrace this brave new world with the warmth and affection that is best compared to a mother and a new borne baby.  Before getting into the technical details of why this "brave new world", is just a rehash of the last "brave new world" promoted by Microsoft, a.k.a. Webforms, let me spell it out to you the reader, who and what Microsoft are aiming this "ugly girl at the dance" at.  


Webforms is now grossly out of favour with the intelligencia of .NET that were formerly the artist known as ALT.NET.  These cool kids have moved onto ASP.NET MVC which follows a more traditional and honest web development model.  It is now a commonly agreed perception that Webforms is a leaky abstraction directed totally at VB6 developers who could not leave the paradigm of statefull VB6 forms behind them.  


Let me illustrate this with a vignette from my employment history…….


I worked as a consultant for a leading educational software provider in London (I am so tempted to mention them by name)  were they had an army of old VB6 developers gleefully and eloquently creating heinous crimes in the field of web development that are analogous to Hitler's holocaust.  Their ignorant approach was to use datasets bound to datagrids throughout the application, not only was the average page size gargantuan with ViewState multiplying exponentially with every postback but they stuffed everything in the Session which was stored in SQL Server.  It was truly unbelievable that something so ugly was being used by the leading educational organisations of the UK.  This is a fairly common web forms shop were square pegs are hammered into round holes who develop time bomb websites that are primed to explode in incendiary expansions of cash.  The very fact that they had to hire consultants like myself to unscramble the mess is testimony that this just did not work.  They got the website up and working quickly and then spent a lot of time and money rewriting it to perform like a high traffic website should.


The type of developer webforms is aimed at is the mission statement of the vast majority of Microsoft products, it is of course the drag and drop world of development.  You simply choose what you want from the designer and press F5, hey presto, you have yourself a piece of demoware software that is held together with double side sticky tape and string and has a shelf life of two days.  Microsoft loves this space, even Scott Hanselman has joined in with this more measured 30 minute application.  This is the developer who Microsoft are aiming this at.  This is the market that EF is marketed at.  They love this shit.  They like impractical apps in 30 milliseconds for shows like MIX.



In development, we often talk about personas, a persona is a mythical user of the system who has the traits of the type of user the software is aimed at.  Let us create the persona of a Silverlight developer, we will call him Bob.  Bob is a lazy fuckwit.  Bob has no real interest in development or doing things right, Bob just wants to cut and paste code from Google whenever he is stuck.  Bob does not look up from the developer world that Microsoft has painted for him, he would never dream of looking at another web framework in order to foster some new ideas.  Bob hates JavaScript and CSS, he has absolutely no interest in learning them.  Bob loves other languages, as long as they are C#.  Poor hapless Bob could not even compile his code if you took Visual Studio away from him, he only ever uses the command line to issue the iisreset command.  Bob will never develop anything that cannot be developed in Visual Studio.  Bob likes the designer surfaces of Visual Studio.  Bob sees Silvelight as a shortcut to browser development which means he can stay totally in the world of C# and not have to learn horrible JavaScript.  Bob has heard of the jaw dropingly cool JavaScript framework called JQuery, but Bob has no idea how something so popular could be written in anything other than C#.  Bob will stay in his blinkered hole, unaware of the outside world that truly is changing to a brave new world.  Bob is exactly who Microsoft want in their development army.  Microsoft do not want you to develop in anything other than Visual Studio or perhaps Expression blend.  They do not want you to learn the ubiquitous browser display language of HTML, they do not even really want you to learn XAML, they want you hooked on your inability to do anything outside of a designer.  Are you a Bob?  Do you ever lift your head above the one world view of visual studio?  I will move onto XAML in a future post but I want to put forth the conspiracy theory that Microsoft prospers from your own inadequacies.  They want you to have a reliance on Visual Studio in the same way as a super fly pimp guy wants his ho's dependant on heroin to gain their dependence.


Another conspiracy theory I have is that Microsoft has got cold feet over IronRuby as it might lead to a further brain drain of the developers formerly known as ALT.NET.  More and more of these guys have had enough after tasting the crack cocaine of Ruby on Rails that gives the addict, the feeling of how efficient a web framework can be.  The IronRuby story is getting picked up by some but not many.  I do not expect to hear Microsoft making any big noises about IronRuby on rails anytime soon.  The majority of the posts I have seen, show how to use IronRuby used with WPF!!  You could not make it up.  I found this example which passes for great ironic humour were the author sets out to show how IronRuby can be used with sharepoint.  Ironic IronRuby on rails is a more fitting title for this total farce that just goes to show how Microsoft or indeed its developers do not get Ruby on Rails and are instead shoe horning IronRuby into impractical and ridiculous places.


In writing this post, I could have very easily just reworded Steve Jobs post about flash and do a search and replace on the word flash and replace it with the word Silverlight.  The arguments against Silverlight are just as valid as those against flash.  I will simply link to the post and let you judge for yourself.  Instead of rewording that post, I wanted to take a different slant on why you should hate silverlight.  I want to paint a warning to anybody actively indulging in silverlight development that you could be making a serious career wrong turn.  The world is changing and HTML 5 is the actual brave new world that Silverlight claimed to be.  By staying in Silverlight, you will be learning skills that cannot be transferred to any other platform.  If you know HTML and JavaScript, you can easily take these skills with you from platform to platform.   Spending every waking hour knee deep in Visual Studio and only ever developing in C# will make you a shallow uneducated developer. 


I think it is worth noting that Microsoft is getting wise to HTML 5 and are now fully embracing it in IE9 with some demoware here.  Do not expect Microsoft to do anything less than drop Silverlight like a stone if HTML 5 is popular on IE9.


There are enough posts written about the joys of HTML 5 for me not to bother mentioning its freshness and newness.  Yes, it is turning into the catchall for anything web related, just like web 2.0 did and apple's HTML 5 is in someways just as proprietary as silverlight but this is the future of the web.  JavaScript and CSS have had a resurrection, not the flaunted death.  The talent of the JQuery team are testimony to who are now developing JavaScript.  Are these similar types of developer drawn to Silverlight like a moth to a flame?  Are the likes of Jim weirich singing the praises about RIA and oData? I think you will find nobody of any note is drawn to this platform in the same way as tired Java developers fled to Ruby on Rails.  oData is another tenant of the strangely name RIA platform.  What oDATA has done to the ATOM specification is nothing short of rape and yet another reason to be truly repulsed by RIA services. 


We no longer need these ugly plugins that do not play by natural browser rules, alienating themselves like inner city ghettos in no go areas of the web page.  We as developers need skills that are transferable.  There is a world outside of Visual Studio that can only progress you as a developer.  Or are you a Bob, blinkered, ignorant and tied, like a dependant crack addict to the rocks of Visual Studio.  Don't be a follower, don't be a sheep and learn to think for yourself.  The pragmatic programmer book stated that you should learn a new language a year, how about learning a language outside of Visual Studio?  If this scares you then you need to seriously do some soul searching or maybe go and work with Bob.


Next I am going to rant about the truly, ugly mess that is XAML.  XAML is an xml grammar that cannot even be defined in an XSD schema because it is so ugly.  XAML is like XHTML only it can crash an IDE.



Friday, 9 April 2010

Invention is not invented here

In keeping with the subject matter, I want to rip off my own Go FUBUMVC yourself post by rehashing the idea and writing about it again.

It is a blatant rip off of the last post.  It is lazy and requires little thought.  I could write about something new but why bother when this is guaranteed to get some traction.

Now on with the show.........

Not a week goes by without my RSS reader mentioning a new .NET OSS project that is a complete rip off of an existing project.

The latest one to sadden my eye is the AutoPoco project by Rob Ashton.  We already have NBuilder and AutoFixture so what on earth do we need another one of these for?  

It then turns out that Karl Seguin or whatever his name is states that he wants to write another validation framework.  Are you absolutely mad? Another one?  We already have 3,089,298 validation frameworks muddying the waters and taking the word diversity to new levels.   What do you really hope to achieve by writing another validation framework?  Maybe we can really abuse lamdas into a totally ridiculous syntax.  Why not put a fluent interface on top of a fluent interface.

I think what saddens me the most is how many man hours are required for the new project to get into a state of parity with the existing project that is being ripped off.  

We will never compete with platforms like Ruby on Rails without invention or innovation.

There are of course some less time consuming acts that you can choose rather than a total rewrite of an existing system:

  1. Get involved with the existing project you are about to rip off.  This will never happen as the developer wants his name on the door.
  2. Fork the code of the existing project and save yourself the hassle of having to write all this crap from the start.
  3. Write another IoC container. 

I am further saddened by the fact that the developers in question are probably quite talented and could put this time to the betterment of the .NET ecosystem.

My theories as to the why of all this blatant plagiarism are this:

it is time consuming to find a worthwhile problem to solve.  

This time could be spent writing code.  Finding a good problem means placing your brain in unfamiliar places.  I know myself how difficult this is after spending two months coming up with a MicroIsv product idea to pursue.  My urge to go down the familiar routes of project management and CRM was strong but I stuck with it and eventually came up with a product I was able to in some ways convince myself has potential and has a market with some good and testable market research.  

I just want to write code

As developers we want to write code, we do not want to create mindmaps or brainstorm through a list of possibilities before going through the whole process again to define the problem space.  I could easily pop out a mocking framework or a .NET build engine in the same time with less effort.

I might fail

I know about failure on this front more than most as in a lot of ways horn has been a failure.  It is certainly a failure in the community I tried to build around it and it still has some failings in the technical solution.  I can though say I tried.  I can also say that my mind was placed in some very unfamiliar and unusual places as I thought about the problem.  With a pre-defined problem space like AutoPoco is ripping off, what do I learn on a non-coding basis.  Free your mind and your ass will follow.

Why not pick an existing problem and rewrite it?  I can change it slightly to my needs and if all else fails, I can always look at the source of the existing problem.

I will now court ultimate controversy and hatred from the .NET community by stating that one of its favourite son's is the ultimate plagiarist.

I speak of course of Ayende, before I list his list of similar projects, I do want to say that the guy has done amazing things for the community and at one point I looked forward to his blog posts with glee.  He has done more than most which is why I find it frustrating that he has not used his talent for more innovative ends.

Did we need another MSMQ with Rhino Queues?
Do we need another document database?
Do we need another memcached clone?
etc., etc.

The answer to all the above is no and I would say his most innovative project to date is NHProf which is ironically commercial.

I expect any Ayende sycophants reading this who take crawling to their master to new and sickening levels to proclaim a jihad against me.

Come and have a go if you think you are hard enough!!!!






















Thursday, 8 April 2010

Rails - Day 17 - Update and Delete

Rails  - Day 1 - The RubyGem Love Story
Rails -  Day 10 - Testing Rails Controllers
Rails -  Day 13 -ActiveRecord Relationships Part II
Rails - Day 15 - Rails Forms Part II

In the last post, we covered off validation.

We have been using a mock application of an expense tracker to illustrate the key points.  The expense records the expenses incurred running a small business.

In this post we want to finish the application off by completing our pseudo application by allowing updates and deletes of existing records.

Below is the index page of our expenses application that will allow a user to edit and delete existing expenses that we can create with our code thus far:


The edit action is analogous to the new action in that it just transfers control to a web page that will allow us to alter the details of an existing Expense model object.

As we mentioned in this post, the edit url takes the form of /expenses/123/edit.

Below is the haml created for each row in the above table:



This generates the following url:


At the moment, the haml that renders the screen below is all contained in the new.html.haml:



We want to abstract the Expense model rendering from the new.html.haml in order to reuse it from the edit.html.haml which is the template the rails runtime will look for by convention whenever a url similar to the one below is called:

/expenses/124/edit

The rails runtime will predictably look for a template named edit.html.haml by convention.

We extract the formbuilder haml and place it in a partial named _form.html.haml and update the new.html.haml to render from the partial:

The :locals => {:f => f} expression passes the formbuilder instance to the partial.

We can now easily create an edit.html.haml that will incorporate the partial:


Next we want to create an edit action in our ExpenseController that will retrieve the @expense instance from the database:


The @expense_types instance variable will contain a collection of all the ExpenseType objects that are mapped from records in the expense_types table.

With these sparse lines of code in place, we can now display an expense model that is ready for editing when we click on the edit link of one of the expense records that are displayed on the index page.

Rails routes several restful actions onto every resource that is generated by adding an entry similar to, map.resources :expenses to the routes.rb file.

The update action is the correct and obvious choice for updating our model.

The intricacies of setting up the relationships between the objects was done in the last post when we used accepts_nested_attributes_for to enable the complex Expense object to be created from the form fields submitted from the above page.

Below is the simple update action in our ExpenseController that will take care of the update or redirect to the edit and



In the above action, we are loading the expense object into memory and then calling the update_attributes method which updates all the attributes of a model from the passed in hash.  If the object is invalid, the saving fill fail and false will be returned.

In the event of a successful call to update_attributes, the user will be redirected to the index page where a confirmation message will be displayed which has been placed in the flash provider.


Deleting a Model

This is probably the simplest action to complete.  The delete link takes the form of the bin icon in the screenshot below.


This link is rendered from the following HAML:

=link_to "",  {:action => "destroy", :id => e.id}, :method => :delete, :class => "icon-delete", :confirm => "Are you sure"

This will render an anchor tag that links to a controller action called destroy and passing in the id of the expense we want to delete.  You can also see that the javascript confirm mechanism can be hooked up with the :confirm => "Are you sure" expression.

Below is the HTML that is rendered from the HAML:

<a href="/expenses/17" class="icon-delete" onclick="if (confirm('Are you sure')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'rW75EzBpl9r103D8zdIzX18upwh1Vs5dyp9RWYhJ31E='); f.appendChild(s);f.submit(); };return false;"></a>

The above link generates a lot of javascript which constructs a form and posts it to the server that will in turn be routed to the destroy action of the ExpensesController

This will call the following action in the ExpensesController:

 We simply retrieve the expense instance and call the destroy method.  We then place the confirmation message in the flash provider and redirect to the index page:

This ends my introduction to rails series. 

You can download the code that I created writing these posts from github here.







Tuesday, 6 April 2010

Rails - Day 16 - Validation

Rails  - Day 1 - The RubyGem Love Story
Rails -  Day 10 - Testing Rails Controllers
Rails -  Day 13 -ActiveRecord Relationships Part II
Rails - Day 15 - Rails Forms Part II
In the last post, we took a deeper look into working with a complex object and the Rails form builder.

We have been using a mock application example of an expense tracker to illustrate the key points.  The expense tracker will record the expenses incurred running a small business.

The complex object in question is an Expense model object that is made up of the following structure:


Below is the form we have constructed to capture an expense structure that is created from the inputs submitted in this form:



One thing that has not been mentioned so far is how to validate the user supplied input that is sent from this form to the server.  In this post we want to ensure that:

  • The External reference input has a value.
  • The posting Description input has a value
  • The user has selected an Expense Type from the dropdown
  • The net field has a valid monetary value added.  The net field is an attribute of the Expense's child object ExpensePayment.

If we take our first requirement from the above, we can create the following unit test to ensure our assertions:


Notice that there is also a test to check that the expense object is valid.  It is important to start from a good position and then assert failures.

In the above test, we are creating a valid @expense object and then setting the field we want to test (external_reference) to nil.

This test obviously fails as no validation instructions have been added on the Expense model.  

Rails Model Validators

When developing a Ruby on Rails application it is a good idea to use ActiveRecord validators to ensure the state of a model before trying a persist it to the database.  This type of validation is also known as first pass validation.

The most common approach is to use the declarative validates_xxxx_of class methods.

In order to make the above test pass, we use the validates_presence_of ActiveRecord class method to ensure an expense has an expense_payment attribute:


Our test now passes.  The validates_presence_of method takes a list of attribute names that we want to ensure have non nil values.  

Other similar attributes are:


We can validate the other attributes that we want to ensure are required like this:

validates_presence_of :external_reference, :description, :expense_date

But what about associated objects?  How can we verify that the user has selected an ExpenseType from the dropdown.  In our model, an Expense belongs to an ExpenseType.

In order to test this, we create the following test:



This type of relationship is very easy to validate.

The above test obviously fails but if we update the model to add the expense_type_id to the list of symbols passed as arguments to the validates_presence_of then all is good.

Our final two requirements concern the has_one  ExpensePayment relationship.  There are two things we need to test:

  • We need to ensure that there is an ExpensePayment child object contained within the Expense object.
  • We need to ensure that the contained child ExpensePayment  object has a non nil name field.

As ever we create the following failing tests:


In order to make the first test pass which ensures that an expense_payment object is contained with in the Expense model, we just update the symbol list validates_presence_of to include the :expense_payment attribute


This will enable our first assertion to pass but the second assertion still fails.

The first step is to add a call to validates_presence_of class method in the ExpensePayment object and include the net attribute.

We then update the  Expense object to include a call to the ActiveRecord validation class method validates_associated.


Above we can see the call to validates_associated :expense_payment which will instruct the framework to include the child object validations of the ExpensePayment model in the @expense.errors array.

With our validation tested, we now need to add the following to our new.html.haml view that will take care of displaying any validation errors:

And that is it, the error_messages_for :expense expression will display any error messages contained within the @expenses.errors array.

Below is how these error messages are displayed on the page.  Obviously you would style the div containing the error messages but as this is post 16, I simply cannot be bothered:


Obviously, this type of validation is very simplistic.  There are many hooks to get into this validation process for more complex scenarios. There are callbacks available on :before_save or :after_save or you can even override the validate_on_create or validate_on_update class methods.

In this post, we have discussed validation at a very high level.

In the next post, we will finish off the series by completing the update and delete actions.



Wednesday, 31 March 2010

Rails - Day 15 - Rails Forms Part II

Rails  - Day 1 - The RubyGem Love Story
Rails -  Day 10 - Testing Rails Controllers
Rails -  Day 13 -ActiveRecord Relationships Part II
Rails - Day 15 - Rails Forms Part II
In the last post we introduced the rails form builder and showed how easy it is to render a simple form using a simple model object.

I want to go into much more detail with a pseudo real example because most of the posts about rails forms and ActiveRecord that I have come across illustrate exactly what I did in the last post and show how to use the form builder and a simple model object.  Nearly all these examples show a simple model with a one to one mapping on a single table.  This is not very real world.

In this post I want to show how to use a form builder with a slightly more complex model.

In the past few posts, we have been building up a simple application that will record the expenses a small business owner might incur. 

Below is the view that is rendered from the new action of the ExpensesControlller where a user will add a new expense:



In the last post we were able to create an Expense object that captured the Paid by Director, Expense date, External reference and Posting Description attributes.

We covered ActiveRecord relationships in this post and defined the relationships between the expense object and its child objects.

The Expense model is a complex object with two child objects defined by the the relationships below. 


We are now going to use the form builder to both set the and retrieve attributes of the child objects through an HTML form.

Our first step is to fill the Expense Type dropdown that you can see in the screenshot at the start of the post with any records that exist in the expense_types table.

The form builder contains a select method which works well for belongs_to relationships.  The first argument of the select method is the foreign key of the belongs_to relationship which in our case is expense_type_id.  

We could create a select method similar to the following which has the ActiveRecord call ExpenseType.all to the database defined in the view and I have seen this done quite a lot:



We could do that but this feels dirty and ugly.  Such a call to the database has no place in our view and instead we add the following code to the new action of the ExpensesController:


The collect method of the array object will iterate over the array and provide a block that allows us to return a new array with different elements.  I think I am right in saying that the map and collect methods are the same.  A new array is created for each element in the original array that contains the id and name needed to render the option elements of the dropdown.

We then update our select method to use the instance variable @expense_types instead of the ActiveRecord call:


This makes me feel much better.  The ExpenseType.all call is now in the controller which of course makes it a lot more testable and tidy than adding it directly to the form builder select method.  We can also mock the call to ExpenseType.all which I prefer for testing purposes over direct database calls.

The select method will take care of the Expense belongs_to ExpenseType relationship.  

There is also a has_one relationship that defines the association between Expense and ExpensePayment as we discussed in this post.  

The ExpensePayment model object will take care of this part of the UI:


We also stated in this post that the VAT and Gross attributes are actually derived fields from the Net attribute.

The calculation for VAT is ((Net / 100) * 17.5) 
The calculation for Gross is (Net + VAT).

So the only attribute we are concerned with recording from the user is the Net attribute.  We should use JQuery and Ajax to update the derived fields Vat and Gross as the user inputs their values.

Nested Attributes

Nested attributes allow you to save attributes on associated records through the parent which is exactly the behaviour we want for our Expense has_one ExpensePayment relationship.  By default nested attribute updating is turned off but you can enable it using the accepts_nested_attributes_for class method.  When you enable nested attributes an attribute writer (property set in .NET speak) is defined on the model.  The attribute writer is named after the association, which means that in our example, a new method will be dynamically added to the Expense model:expense_expense_payment=

Enabling nested attributes on a one to one association allows us to create both the Expense and Expense_payment in one go from a params hash that would be passed in from a rails form builder generated form.

In order to test this, we create the following failing test:


You can see from the above that the hash contains a child hash named :expense_payment_attributes that will represent the child ExpensePayment model object.  To make the above test pass, we update the Expense model to the following:


The changes have incorporated the following:

  1. To make the expense_payment attributes available through nested forms we need to add the :expense_payment_attributes convention to the attr_accessible method.  We mentioned  attr_accessible in the last pos tand this method restricts what methods can be accessed via a web form.  This is often overlooked and is a potential security hole.  Shame on you if your models do not include this.
  2. We define the relationship as nested by using the accepts_nested_attributes_for method.
  3. We have also updated the has_one statement to has_one :expense_payment, :dependent => :destroy which tells ActiveRecord to cascade the delete of the child object when the Expense is deleted.

Nested Model Form

In the view that will render the new action, we simply use the fields_for method to expose the fields of the nested model:



It is worth mentioning that we are using the text_field_tag method instead of the text_field method for the readonly attributes vat and gross.

This will generate the following HTML:



You can see that the p.text_field :net expression has generated an input text element with a name attribute of expense[expense_payment][net] which models the Expense has_one ExpenseType relationship and is what rails uses to build the params hash of the relationship.

If we inspect the params hash that is passed to the create action of the ExpenseController by adding the code raise params.to_yaml to the action, we get the following output:


You can see that the expense_payment_attributes hash is nested within the parent expense hash.  This means that we can create an expense object from the form fields in our create action:

We are going to mention validation in the next post but if we now fill out the required fields and submit the form, the create action completes successfully.

In order to check that the ExpensePayment has made it into the database, we can spark up the rails console with the command ruby script/console and enter the expression ExpressionPayment.all.


We can see from the above that our relationship is successfully created.

I wanted to write this post because in my opinion, a lot of the posts on rails forms do not go into this level of detail for defining relationships.

I personally do not like having to add the accepts_nested_attributes_for method and would like the framework pick this up automatically.  If anyone who knows rails better than me can suggest a better way than this or maybe argue that this way is a good way then please leave a comment.

In the next post, I am going to touch on how to validate your rails model.


Rails - Day 14 - Rails Forms Part I

Rails  - Day 1 - The RubyGem Love Story
Rails -  Day 10 - Testing Rails Controllers
Rails -  Day 13 -ActiveRecord Relationships Part II
Rails - Day 15 - Rails Forms Part II
In the last post we finished off our sparse introduction to Rails ActiveRecord.  

We have now created the UI shell of our example application and we also have tested and defined our model that reflects the job in hand.  We re now ready to complete the server side code to tie the two together.

At the time I was writing this post, ASP.NET MVC 2.0 has just arrived and it is fairly obvious that they have taken a lot of their new ideas for their form builders from the rails form builders. 

We have already defined mark up for how the page will look



At the moment our new.html.haml page looks like this:


We have a simple table contained in a div.

Form Helpers

We are now going to refactor our page to take advantage of the Form helpers that come as part of the Rails library.  Form helpers are designed to make working with models easier compared to using standard HTML elements by providing a set of methods for creating forms based on your models.  The core method of this helper, form_for, gives you the ability to create a form for a model instance.  This helper generates the HTML for forms, providing a method for each type of input (e.g. text, password, select etc.).  When the form is submitted, the form inputs will be bundled into the params object and passed back to the controller.

In our example, we are going to create a form for the expense model object.  First we will only work on saving the Expense object and then move onto saving the Expense's child objects ExpenseType and ExpensePayment objects.  To take advantage of the rails form helpers, we refactor the above haml to the following:



The form_for method is possibly the most popular helper used when generating a form that binds to one type of object.  The parameter you pass through fomfor f is of type FormBuilder which offers the other methods you can see like check_box, date_select, text_field, text_area etc.

The above will generate the following HTML:



You can see from the above that the form is going to post to the /expenses url.  This URL is identical to the index action url of the ExpensesController but you should also notice that the method of the form above is of type post.  Rails maps the plural url and the post method to an action called create that is one of the seven default actions that rails creates for us with every resource we create. 

Another item of noteworthy mention is how the formbuilder has constructed the name fields of the inputs that you can see in the above html.  For example the checkbox for the Paid by Director field has a name attribute of expense[paid_by_director] which has been generated from the check_box method:

=f.check_box :paid_by_director,  { :class => 'check' }

When we submit this form rails will use nesting to nest the paid_by_director attribute inside a hash called expense.  Rails uses this to group the attributes of a single model inside a single hash.

It is also worth noting that for the checkbox, the formbuilder has generated 2 inputs for the f.check_box call.  One input is obviously of type checkbox but the other is a hidden field.  The hidden field is used to record the state of the checkbox when it is posted.  If a checkbox is not checked then it will not appear in the form post collection.  In this case rails will use the value in the hidden field.

When the form is submitted, the form inputs will be bundled into the params hash.

As I have mentioned in the last couple of posts, we are being good little TDD soldiers and because of this, we create the following functional test or controller test to test the create action of the .  I introduced functional testing in this post.

We create the following test to test passing the form fields to the form:




This is exactly the type of hash that gets routed to the create action of our ExpensesController from the above HTML form that is generated from our HAML.

If we want to know exactly what values are being passed to our create action, we can create add the following code to the create action:

Which will display the values of the params hash that is created when the submit button is clicked and should display something like the following in your browser of choice:

Another way of doing this is to change the action to the following:

Here we are raising an exception and calling the to_yaml method of the params hash to display the details of the hash hierarchically:


This will of course cause our test to fail so we will fall back to the original.

We have now tested that our create expense form is hooked up correctly.  We now need to add the code to complete the deed of creating a new expense.  We do this test first.

We update the previously created functional test to the following which is pretty reflective of a full functional test:


We are using flexmock to mock out the ActiveRecord calls as I am not a great believer in writing tests that run against the database.

We mock out the class methods of the Expense object to return exactly what we want to drive our tests in a more logical manner.

We then write the code to make the create action pass:

From the above, you should notice the following:

  1. We are creating a new Expense instance from the params hash that contains the form fields.  We are assigning this new object to the @expense instance variable.  This technique of setting multiple attributes at one time on a model is called mass assignment.
  2. The ActiveRecord save method returns a boolean that indicates whether the save was successful or not.
  3. In the event of a successful save, we are placing a notice in the flash provider and redirecting the index action which we access using the short cut convention expenses_url.  The flash provider is a way to pass temporary objects between actions.   Anything you place in the flash will be exposed to the very next action and then cleared out.  This is a great way of doing notices and alerts.  I seem to remember something similar in Castle.Igloo that later became Rhino.Igloo.
  4. If the save was not successful, we redirect back to the new action.

One problem that is often ignored with mass assignment is that any method can be called from a model that is contained in the params hash including database calls.  In order to prevent this we add the attr_accessible  method to our model and define the methods that we want editable.  To accomplish this, we update the Expense model class:


If we the save is successful, the browser will be redirected to the index action that displays all the Expenses.  We need to update the code to actually render the expenses from the database.

In order to do this, we add a new functional test that checks that the index method runs with records in the database:


Now we update our index.html.haml to the following:



If we successfully insert a record, we are greeted with the following confirmation in the expenses index view:

This post is much longer than I intended so I will leave things here.

In the next post, I will illustrate how to save the Expense as a whole.  This will include the child objects that are part of the complex expense object.