Extracting Code into Helper Functions

Problem

Your views are getting cluttered with Ruby code.

Solution

Lets create a controller with a fairly complex view to see how this can happen:

	$ ./scripts/generate controller list index
	 exists app/controllers/
	 exists app/helpers/
	 create app/views/list
	 exists test/functional/
	 create app/controllers/list_controller.rb
	 create test/functional/list_controller_test.rb
	 create app/helpers/list_helper.rb
	 create app/views/list/index.rhtml

Edit app/controllers/list_controller.rb to look like this:

	class ListController < ApplicationController
	 def index
	 @list = [1, "string", :symbol, [list]]
	 end
	end

Edit app/views/list/index.rhtml to contain the following code. It iterates over each element in @list, and prints out its index and the SHA1 hash of its object ID:

	
	
    <% @list.each_with_index do |item, i| %>
  • <%= i %>: <%= SHA1.new(item.id.to_s) %>
  • <% end %>

This is pretty messy, but if youve done much web programming it should also look sadly familiar.

To clean up this code, we e going to move some of it into the helper for the controller. In this case, the controller is called list, so its helper lives in app/helpers/list_helper.rb.

Lets create a helper function called create_li. Given an object and its position in the list, this function creates an

  • tag suitable for use in the index view:

    	module ListHelper
    	 def create_li(item, i)
    	 %{
  • #{i}: #{SHA1.new(item.id.to_s)}
  • } end end

    The list controllers views have access to all the functions defined in ListHelper. We can clean up the index view like so:

    	
    	
      <% @list.each_with_index do |item, i| %> <%= create_li(item, i) %> <% end %>

    Your helper functions can do anything you can normally do from within a view, so they are a great way to abstract out the heavy lifting.

    Discussion

    The purpose of helper functions is to create more maintainable code, and to enforce a good division of labor between the programmers and the UI designers. Maintainable code is easier for the programmers to work on, and when its in helper functions its out of the way of the designers, who can tweak the HTML here and there without having to sifting through code.

    A good rule of thumb for when to use helpers is to read the code aloud. If it sounds like nonsense to someone familiar with HTML, or it makes up more than a short English sentence, hide it in a helper.

    The flip side of this is that you should minimize the amount of HTML generated from within the helpers. That way the UI designers, or other people familiar with HTML, won wander your code, wondering where to find the bit of HTML that needs tweaking.

    Although helper functions are useful and used very often, Rails also provides partials, another way of extracting code into smaller chunks.

    See Also

    Recipe 15.14, "Refactoring the View into Partial Snippets of Views," has more on partials



  • Strings

    Numbers

    Date and Time

    Arrays

    Hashes

    Files and Directories

    Code Blocks and Iteration

    Objects and Classes8

    Modules and Namespaces

    Reflection and Metaprogramming

    XML and HTML

    Graphics and Other File Formats

    Databases and Persistence

    Internet Services

    Web Development Ruby on Rails

    Web Services and Distributed Programming

    Testing, Debugging, Optimizing, and Documenting

    Packaging and Distributing Software

    Automating Tasks with Rake

    Multitasking and Multithreading

    User Interface

    Extending Ruby with Other Languages

    System Administration



    Ruby Cookbook
    Ruby Cookbook (Cookbooks (OReilly))
    ISBN: 0596523696
    EAN: 2147483647
    Year: N/A
    Pages: 399

    Flylib.com © 2008-2020.
    If you may any questions please contact us: flylib@qtcs.net