Ruby on Rails

New Rails feature: simply_helpful

New Rails feature: simply_helpful by Scott Matthewman

UPDATE: Thanks to everybody who’s linking to this blog post, especially the mighty DHH himself. It’s worth pointing out that simply_helpful development is proceeding apace. Some of the bugs mentioned have been fixed; there are additional helpers that aren’t covered here; and, as a plugin that’s very, very new, simply_helpful may well change at short notice.

UPDATE 2: The company I work for is looking for Rails developers who are also comfy maintaining PHP code. View our job ad for more. (Done. Look forward to our first big public Rails app sometime in the summer!)

UPDATE 3: DHH linked to me again — thanks David, and welcome to all you hundreds of new visitors!

A new plugin appeared in the Rails SVN overnight, it seems. Named simply_helpful, the intention seems to be to simplify some of the most common uses of helper functions.

I suspect that these changes have been implemented as a plugin so that they don’t impinge on anybody running Edge Rails until they’re 100% stable and 100% backwards-compatible. So, if you want to explore the changes right now, you’ll have to install the plugin in your project yourself:

script/plugin install simply_helpful

With the new plugin installed, some basic helpers get simplified. For example, in my index.rhtml for my Venues controller, I used to have:

<table>
  <tr><th>Name</th> <th>City</th> <th>Postcode</th></tr>
  <%= render :partial => 'venue', :collection => @venues %>
</table>

An aside: that’s a greatly simplified version of the table; I’ve cut out a lot of stuff that would get in the way of seeing what simply_helpful is doing.

But, given that Rails can tell that my @venues array is populated with Venue instances, the new helper doesn’t need me to explicitly name the partial I’m using:

<table>
  <tr><th>Name</th> <th>City</th> <th>Postcode</th></tr>
  <%= render :partial => @venues %>
</table>

So the :collection key becomes redundant (we’re passing an Array, so a collection can be assumed), as does the naming of the partial component itself — simply_helpful automatically derives the location from the passed objects’ class — in this case, as it’s a collection of Venue objects, the partial in question is assumed to be venues/_venue.rhtml.

Along with the collection partials rendering as outlined above, you also get the following (from what my limited Ruby-brain can tell from deciphering the as-yet-undocumented code):

DOM ID attributes

<%= dom_id(object, prefix = nil) %>

Will provide an HTML ID attribute value for an onscreen object based on the object’s class and database ID. For example, dom_id(@person), where @person is a Person instance with a database ID of 123 would return person_123. If the object hasn’t been saved to the database yet, the id will be new_object_name.

By tying this feature into enhancements for RJS helpers, it means that you can now directly link DOM objects on the page to the data objects they represent. The following are now identical in meaning:

page[:person_123]
page[dom_id(@person)]
page[@person]

Pretty nifty.

DOM Class names

<%= dom_class(object) %>

Creates a CSS class name based on the object’s class — so a ProductionType object would get a DOM class of production_type.

On its own, this new function maybe isn’t as exciting as the dom_id and render improvements, but it’s used in the next feature, and it’s encouraging good practice by having clear, readable and consistent class names for your DOM objects.

Form blocks

The new form_for syntax combines with the new Restful Routes, to greatly simplify the form setup:

  • The form’s action points to an update or create action, depending on whether your object has previously been saved.
  • The form will automatically get a DOM id of new_object or edit_object_# (where object is the object’s class name, and # is its database ID), depending on whether it’s a new form or not
  • The form will also automatically get a class name of either new_object or edit_object (again, where object is your object’s class name)

This means that calls to form_for get massively simplified. For example, this line would now work for both new and existing Venue instances:

<% form_for @venue do |f| %>
...

For an existing venue object, that would produce:

<form action="http://localhost:3000/venues/123" class="edit_venue" id="edit_venue_123" method="post">
<input name="_method" type="hidden" value="put" />

whereas the same line of code would, for a new venue object, produce:

<form action="http://localhost:3000/venues" class="new_venue" id="new_venue" method="post">
<input name="_method" type="hidden" value="post" />

Unfortunately, as of right this second (revision 5050), it’s a teensy bit broken. There’s an assumption of an :html option hash being present, so I could only get it to work by changing the above line to < % form_for @venue, :html => {} do |f| %> (this is now fixed).

It also doesn’t support custom form builders yet, which I’m using in my project to automatically attach labels to fields, and to visually demarcate required fields from optional ones (I fixed this! Yay me! :-) )

But then, simply_helpful is less than a day old — these bugs will get ironed out pretty quickly. And when they do, Rails will have yet another way in which it encourages you to write simpler, better code, in a way that’s 100% backwards-compatible.

Credit where it’s due: this post by Marcel Molina Jr. helped me figure out my way round the plugin code.

Story written by Scott Matthewman

Formerly Online Editor and Digital Project Manager for The Stage, creator of the award-winning The Gay Vote politics blog, now lead developer for evvnt.com, critic for Musical Theatre Review, The Public Reviews and others.

@scottm

 3

  1. [...] is used all the time to identify multiple records on one html page. It turns out that Rails 2 has Simply Helpful’s cute little helpers on board! So instead of that thing above, you just write [...]

Leave a Reply