Tailoring the Generated Scaffold Code  Hot PDF Print E-mail
Tag it:
Delicious
Furl it!
Digg
NewsVine
Reddit
YahooMyWeb
Technorati
Articles Reviews Ruby
Written by Bogdan V   
Tuesday, 12 December 2006

{mos_sb_discuss:50}

The code generated by the Scaffold script is perfectly usable ‘out of the box’, and is robust once you have added enough validation into your data model. However, if that’s all there was to developing Rails applications, then programmers would be out of a job, which would clearly not be a good thing :-) So let’s do some tailoring:
 


 


The Controller In a ‘List’ view, I would expect the records to be displayed in alphabetical order. This requires a minor change to the controller:

app\controllers\categories_controller.rb (excerpt)
def list
    @category_pages, @categories = paginate :category,
         :per_page => 10, :order_by => 'category'
end

In this application, the show screen is unnecessary – all the fields fit comfortably on a single row on the screen. So, def show can disappear, and let’s go straight back to the list screen after an ‘Edit’:

app\controllers\categories_controller.rb (excerpt)
def update
    @category = Category.find(@params[:id])
    if @category.update_attributes(@params[:category])
      flash['notice'] = 'Category was successfully updated.'
      redirect_to :action => 'list'
    else
      render_action 'edit'
    end
  end

 
The flash message will be picked up and displayed on the next screen to be displayed – in this case, the list
screen. By default, the scaffold script doesn’t display flash messages - we’ll change this in a minute – see below.

The View

Displaying Flash Messages

Rails provides a technique for passing ‘flash’ messages back to the user – e.g. an ‘Update Successful’ message which displays on the next screen and then disappears. These can be picked up easily with a small change to the Layout (adding it to the Layout means it will appear on any screen):

app\views\layouts\categories.rhtml<html> <head>   <title>Categories: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
</head>
<body>
<h1><%=@heading %></h1>
<% if @flash["notice"] %>
<span class="notice">
  <%=h @flash["notice"] %>
</span>
<% end %>
<%= @content_for_layout %>
</body>
</html>


A simple addition to the stylesheet makes the flash message more conspicuous:

public\stylesheets\scaffold.css (excerpt)
.notice {
    color: red;
}


Sharing Variables between the Template and Layout

Note that I’ve moved the <h1>...</h1> heading text out of the Template into the Layout so that it appears
above the flash message. As each template will have a different heading, I need to set the value of the variable @heading in the Template. Rails is quite ok with this – Template variables are available to Layouts at rendering time.

I’ve made this change and some formatting changes to come up with my finished template:

app\views\categories\list.rhtml
<% @heading = "Categories" %>
<table>
  <tr>
    <th>Category</th>
    <th>Created</th>
    <th>Updated</th>
  </tr>
<% for category in @categories %>
  <tr>
    <td><%=h category["category"] %></td>
    <td><%= category["created_on"].strftime("%I:%M %p %d-%b-%y") %></td>
    <td><%= category["updated_on"].strftime("%I:%M %p %d-%b-%y") %></td>
    <td><%= link_to 'Edit', :action => 'edit', :id => category %></td>
    <td><%= link_to 'Delete', {:action => 'destroy', :id => category},
            :confirm => "Are you sure you want to delete this category?" %></td>
  </tr>
<% end %>
</table>
<br />
<%= link_to 'New category', :action => 'new' %>
<% if @category_pages.page_count>1 %>
<hr />
Page: <%=pagination_links @category_pages %>
<hr />
<% end %>

• I don’t like the default date format, so I use a Ruby method strftime() to format the date and time fields
the way I want them. Pagination_links creates a basic HTML link bar for the given paginator

Tidying up the Edit and New Screens

A few changes to the Partial used by ‘New’ and ‘Edit’: use a table to improve the layout; get rid of the unwanted created_on/updated_on labels; and prevent the user typing too much into the Category field:

app\views\categories\_form.rhtml
<%= error_messages_for 'category' %>
<table>
<tr>
  <td><b><label for="category_category">Category:</label></b></td>
  <td><%= text_field "category", "category", "size"=>20, "maxlength"=>20 %></td>
</tr>
</table>


and a few minor changes to the two templates (note in particular the use of @heading)::

app\views\categories\Edit.rhtml
<% @heading = "Edit Category" %>
<%= start_form_tag :action => 'update', :id => @category %>
  <%= render_partial "form" %>
  <hr />
  <%= submit_tag "Save" %>
<%= end_form_tag %>
<%= link_to 'Back', :action => 'list' %>
app\views\categories\New.rhtml
<% @heading = "New Category" %>
<%= start_form_tag :action => 'create' %>
  <%= render_partial "form" %>
  <hr />
  <%= submit_tag "Save" %>
<%= end_form_tag %>
<%= link_to 'Back', :action => 'list' %>


User reviews

There are no user reviews for this item.

Add new review




Powered by jReviews

Last Updated ( Sunday, 08 July 2007 )
 
< Prev   Next >