Sunday, January 24, 2010

Recipe 13: Make Pretty Graphs

(This post is one of a series that upadates Chad Fowler's Rails Recipes.)

The main difficulty I encountered with this recipe was figuring out everything that needed to be installed to make it work. One of the difficulties is that upstream configuration choices must be made so that downstream compilations are successful. Here are the steps I found necessary on Ubuntu:

  1. Install jpegsrc. This library is available from www.ijg.org. The instructions tell you that if you want to build from this library, you should execute make install-lib and copy some of the header files to /usr/local/include. I found that copying the files was necessary.

  2. Install libpng. Available from www.libpng.org.

  3. Install ImageMagick from source. It is available at www.imagemagick.org. For this to work, though, it must be configured in a special manner. The necessary configuration command is:
    ./configure --disable-static --with-modules --without-perl --without-magick-plus-plus --with-quantum-depth=8
    Then one does a standard sequence of commands:
    • make
    • make check
    • sudo make install
    The advanced ImageMagick Linux installation instructions suggest that you might require the following command:
     sudo ldconfig /usr/local/lib
    This seems to be necessary.

  4. Install the rmagick gem.

  5. Install the gruff gem.

Only one other minor change was needed to make the recipe work. The graph_controller.rb needs the addition of the line

require 'code_statistics'

Recipe 12: Custom Form Builder

(This post is one of a series that upadates Chad Fowler's Rails Recipes.)

What. Rails comes with a form builder but it is possible to override it and create one's own. This recipe shows how one can make a tabular form builder.

How. The main trick is to derive a class from ActionView::Helpers::FormBuilder in app/helpers/application_helper.rb. The derived class needs to override all the field helpers in the base class.

Anachronism. The meta-programming Chad Fowler recommends loops over the field helpers with some exceptions, i.e., the text includes the following:

(field_helpers - %w(check_box radio_button hidden_field)).each do

What has changed is that field_helpers now returns an array of symbols not strings. Thus, the line should now read:

(field_helpers - [:check_box, :radio_button, :hidden_field]).each do

Recipe 10: Smart Pluralization

(This post is one of a series that upadates Chad Fowler's Rails Recipes.)

Rails has a mechanism for tracking the singular and plural forms of nouns. One is likely to want to supplement the rules that it uses. This recipe describes how to do that, but Rails now makes the process even easier. Rather than putting the change in config/environment.rb, there is a separate file for such rules in config/initializers/inflections.rb. That file even has sample code that is more current than what appears in the text.

Recipe 7: JavaScript Autocompletion

(This post is one of a series that upadates Chad Fowler's Rails Recipes.)

Aside from file naming, this recipe contains is just one anachronism. The code in book_controller.rb uses the non-existent @header variable. It should now read:

  def authors_for_lookup
@authors = Author.find(:all)
render :layout => false, :content_type => 'text/javascript'
end

Saturday, January 23, 2010

Recipes 5 and 6

(This post is one of a series that upadates Chad Fowler's Rails Recipes.)

The next two recipes require only minor changes. For recipe 5, acts_as_list is now a plugin. Otherwise, it works as written. With recipe 6, the change is even more minor: the name of the JavaScript template file is now change.js.rjs rather than simply change.rjs.

Friday, January 22, 2010

Recipe 4: Autocomplete a text field

(This post is one of a series that upadates Chad Fowler's Rails Recipes.)

What. This recipe describes how to implement auto-completion of text fields.

How. Essentially this is done by wiring the Ruby up to the auto completion.

Anachronisms. The auto_complete plugin is now required. This functionality, once part of Rails, has been removed.

Bug. The auto_complete plugin in turn appears to have a bug. The JavaScript methods are expecting to see something returned of the form

  <ul>
<li>Choice One</li>
<li>Choice Two</li>
</ul>

Instead, the plugin seems to return something of the form

  <ul>[<li>Choice One</li>,<li>Choice Two</li>]</ul>

This can be fixed. In the plugin file auto_complete_macros_helper.rb, the last line of the method auto_complete_result is

  content_tag("ul", items.uniq)

This should read

  content_tag("ul", items.uniq.join(""))

Recipe 3: Showing a Live Preview

(This post is one of a series that updates Chad Fowler's Rails Recipes for Rails 2.)

What. The RedCloth gem is used to preview formatted text the user enters.

Anachronism. The only anachronism in this recipe concerns the change in how forms are typically built. In place of the form code in the text, something like the following is needed:

<% form_for @entry,  
:url => {:action => "save"},
:html => { :id => "entry-form"} do |f| %>
<br/><%= f.text_field :title %><br />
<br/><%= f.text_area :body, :rows => 3 %><br />
<%= submit_tag "Save" %>
<% end %>

Wednesday, December 30, 2009

Recipe 2: In place editing with drop-down

(This post is one of a series that updates Chad Fowler's Rails Recipes for Rails 2.x.)

What. Like the first recipe, this one provides in-place editing. It is in-place editing of a country field. Instead of a text field, the editor control is a drop down list of countries.

How. The in-place editor plugin is extended to add this functionality.

Anachronisms.

  1. In place editing was moved out of Rails with version 2, so you will need the in placed editor plugin.

  2. The country list also moved out. Unfortunately, lists of countries are not without controversy, e.g., is Taiwan a country or a province? So there are multiple plugins that provide lists of countries.
  3. Some changes to the Scriptaculous interface require that another option be passed to Ajax.InPlaceSelectEditor.

Modifications.

1. The method in app/helpers/application_helper.rb should look like this:

  def in_place_select_editor(field_id, options = {})
js_options = {}
# Necessary for the submit to work
js_options['callback'] = "function(form) { return #{options[:with]} }" if options[:with]
# Necessary for the options to show up
js_options['selectOptionsHTML'] = %('#{escape_javascript(options[:select_options].gsub(/\n/, ""))}')

function = "new Ajax.InPlaceSelectEditor("
function << "'#{field_id}', "
function << "'#{url_for(options[:url])}'"
function << (', ' + options_for_javascript(js_options)) unless js_options.empty?
function << ')'

javascript_tag(function)
end

2. The following line must be added to the controller:
in_place_edit_for :contact, :country

Saturday, December 26, 2009

Recipe 1: In-Place Form Editing

(This post is one in a series of updates Chad Fowler's Rails Recipes.)

What is it. A field can be used for both display and editing. It initially appears normally. When clicked, it becomes an edit field.

How. This is done through a Scriptaculous control. The recipe describes how to get Rails to use it.

Main modification. One reason this recipe no longer works is that much of what used to be in Rails 1.0 became a plugin for Rails 2.0. So the rails-in_place_editing plugin is required.

Here are the other differences between the book and current Rails behavior:


  1. The call to script/generate should now include column names, e.g.

    ruby script/generate scaffold Contacts name:string email:string phone:string

  2. The forms built by scaffolding are now different. The excerpts in the book will snippet no longer reflect what scaffolding creates. You won't find this in show.html.erb:
    <% for column in Contact.content_columns %>
    <p>
    <b><= column.human_name %> <= h @contact.send(column.name) %>
    </p>
    <% end %>
    One reason you don't see this is that the loop above would cause the timestamp fields that Rails creates by default to appear with along with name and address. Generally, we do not want the user editing those fields. Instead the loop is now unrolled. You'll see elements like this for phone:
    <p>
    <b>Phone:</b>
    <%=h @contact.phone %>
    </p>

Rails Recipes by Chad Fowler

Chad Fowler's book Rails Recipes is both useful and outdated. Built on Rails 1.0, few of its recipes work verbatim. My goal in this first series of posts is to update his recipes so that others can use them.