Friday, February 6, 2009

This Week in Edge Rails

Posted by Mike Gunderloy

January 31, 2009 – February 6, 2009

The big news in edge Rails this week, of course, is the release of Rails 2.3.0 RC1. There’s been a fair amount of activity in the days since that happened, much of it concerned with tidying things up and fixing bugs based on early adopter issues and feedback. Thanks for all the testing, and by all means keep it up!

Nested Form Support in Active Record and Action Pack

This one is big enough that it got a whole blog entry of its own (the version that was committed has minor changes from what you’ll see there). There are two main parts to this commit. First, Active Record can now update the attributes on nested models directly, provided you tell it to do so:

class Book < ActiveRecord::Base
  has_one :author
  has_many :pages

  accepts_nested_attributes_for :author, :pages

Turning on nested attributes enables a number of things, including automatic (and atomic) saving of a record together with its associated children, and child-aware validations. But the big visible one is nested form support. Provided the parent model accepts nested attributes for the child objects, you can create nested forms using form_for and field_for. These forms can be nested arbitrarily deep, allowing you to edit complex object hierarchies on a single view without excessive code. For example, given this model:

class Customer < ActiveRecord::Base
  has_many :orders

  accepts_nested_attributes_for :orders, 
    :allow_destroy => true

You can write this view in Rails 2.3:

<% form_for @customer do |customer_form| %>
    <%= customer_form.label :name, 'Customer Name:' %>
    <%= customer_form.text_field :name %>

  <!-- Here we call fields_for on the customer_form builder instance.
   The block is called for each member of the orders collection. -->
  <% customer_form.fields_for :orders do |order_form| %>
        <%= order_form.label :number, 'Order Number:' %>
        <%= order_form.text_field :number %>

  <!-- The allow_destroy option in the model enables deletion of
   child records. -->
      <% unless order_form.object.new_record? %>
          <%= order_form.label :_delete, 'Remove:' %>
          <%= order_form.check_box :_delete %>
      <% end %>
  <% end %>

  <%= customer_form.submit %>
<% end %>

For more information, see Ryan Daigle’s excellent What’s New in Edge Rails: Nested Object Forms.


Rails Guides Rework

The Rails Guides have switched from using AsciiDoc markup to using Textile markup. This has a couple of benefits: first, it makes it easier to contribute to a guide. Second, it means that we can dispense with the compiled HTML versions of the guides in the Rails tree, because we can assume any developer can build from Textile. There’s a spiffy new look for the Guides web site too – check it out at the beta site.


Scaffolding Changes

There were some cleanups to the code produced by script/generate scaffold – nothing too major, but they bring the controller and views more into line with current Rails best practices. Along the same lines, the “Riding the Rails” index.html page generated in new Rails applications now includes a link to the Rails Guides.

commit commit commit