• Home
  • About

stonean

Feeds:
Posts
Comments

Generator: Stage

January 31, 2008 by stonean

Update: Stage has become a gem and project details can be found at stonean.com

This post was updated on 04-27-08 to reflect the improved design. I’m using the RubyOnRails methods as this is where Stage was born, but Stage is available for Merb as well.

I’ve just completed a new generator called stage. This is a direct copy/modification of the scaffold generator included with Rails 2.0.2.

Stage was born out of a desire to remove as much code as possible from the view. I didn’t want to create a new markup, I wanted to use the existing architecture more efficiently.

To use Stage, you first need to grab it:

sudo gem install stage

Then you use stage just like scaffold:

./script/generate stage author first_name:string last_name:stringexists  app/models/exists  app/controllers/exists  app/helpers/create  app/views/authorsexists  app/views/layouts/create  app/views/data/create  app/views/authors/index.html.erbcreate  app/views/authors/show.html.erbcreate  app/views/authors/new.html.erbcreate  app/views/authors/edit.html.erbcreate  app/views/authors/_form.html.erbcreate  app/views/authors/_data.html.erbdependency  modelexists    app/models/exists    test/unit/exists    test/fixtures/create    app/models/author.rbcreate    test/unit/author_test.rbcreate    test/fixtures/authors.ymlcreate    db/migratecreate    db/migrate/001_create_authors.rbcreate  app/controllers/authors_controller.rbcreate  app/helpers/authors_helper.rbroute  map.resources :authors

So, what’s different? With the exception of the index view, the contents have changed quite a bit.

Edit:

<h1>Editing Author</h1>

<%= render :partial => "form" %>

<%= link_to 'Show', @author %> |<%= link_to 'Back', authors_path %>

New:

<h1>New Author</h1>

<%= render :partial => "form" %>

<%= link_to 'Back', authors_path %>

Show:

<%= render :partial => "data" %><%= link_to 'Edit', edit_author_path(@author) %> |<%= link_to 'Back', authors_path %>

And theres a new partial called form. As you can see this is called by edit and new:

<%submit_label = "Update"submit_label = "Create" if @author.new_record?-%>

<%= error_messages_for :author %>

<% form_for(@author) do |f| %>  <%= render :partial => "data" %>  <p> <%= f.submit submit_label %> </p><% end %>

We’ve now removed the duplication in new, edit and show by having them all reference the data partial.

I’ve had this construct for a while, but the data partial always ended up with too much code. If I’m in edit mode, show the input tag, else show the text, etc…, etc…

It could get rather ugly. So, I decided to really start using the helpers. I have used them before when there would have been “too much” code in the view. I guess I’ve changed my definition of “too much”.

Here’s the data partial:

<p>  <b>First name</b><br/>  <%= author_first_name_value %></p><p>  <b>Last name</b><br/>  <%= author_last_name_value %></p>

As you can see I am calling a <model>_<attribute>_value method which will give me back the correct form or show value. This construct is used to avoid naming collisions. I had initially designed it without namespacing the methods with the model name, but quickly discovered that was a bad idea.

The @action_name instance variable determines how I’m to render the information. Luckily both Merb and Rails have this same variable.

These methods are defined in the Helper:

module AuthorsHelper  def author_first_name_value   if @action_name == "show"     h @author.first_name   else     text_field_tag "author[first_name]", @author.first_name   end  end

  def author_last_name_value   if @action_name == "show"     h @author.last_name   else     text_field_tag "author[last_name]", @author.last_name   end  endend

I opted on creating a method for each attribute and a clearly outlined “if” block to make modifications easier.

I hope you find this useful and it fits your idea of view structure.

Btw, thanks to Greg Houston for his source formatting tool. It made this post look a lot better than it would have without it.

Posted in RubyOnRails, Stage | 4 Comments

4 Responses

  1. on February 1, 2008 at 12:06 am Donald H.

    cool.


  2. on April 27, 2008 at 5:21 pm Jamie Macey

    This is similar to what I’m doing in my own projects. The main differences are that I name _data.html.erb _author.html.erb, in such a way that it can be used as a partial in other actions (like Article). Of course, that precludes using your “smart” helpers that will just wind up being a maintenance pain as the data model evolves over time.


  3. on April 27, 2008 at 5:27 pm Jamie Macey

    It occurs to me that meta-defining the helper methods would go a long way to making it more maintainable, without a significant runtime penalty as one might get with a method_missing hook. Apologies for the crappy formatting, blogger’s a bit draconic about pre/code tags.

    module AuthorsHelper
    %w(first_name last_name).each do |field|
    eval < <-DEF
    def author_#{field}_value
    if @action_name == “show”
    h @author.#{field}
    else
    text_field_tag “author[#{field}]“, @author.#{field}
    end
    end
    DEF
    end
    end


  4. on April 27, 2008 at 6:33 pm Andrew Stone

    Thanks for the comments Jamie. I don’t think having _data as opposed to _author should prevent any code sharing. You would need to qualify the paths anyway. Am I missing something there?

    Other people have mentioned method_missing and constructs similar to your array usage. It’s cool and eliminates a bunch of repetitive code, but I’m just not a fan of this sort of code architecture. As soon as one of the fields differ (password, size, style, etc..) you have to do more work to make a change than you would with the current construct.

    Basically this construct is there with the assumption that something is going to change. So, I think it’s more maintainable this way…interesting how we have different takes on maintainability.

    However, it’s just not mine anymore now is it? :)

    If others express the same wants I don’t see why I couldn’t add a flag in to the generator to provide different templating formats.

    I know it needs to be smarter than it is now and will be working on that in the near future.

    Thanks again for the comments. They are very much appreciated :)



Comments are closed.

  • Open Source


    Lockdown (GitHub)
    RuHL (GitHub)

  • Recommend Me

  • twitter: stonean

    • @ubermuda that's good to know, thank you! 1 day ago
    • @chanmix51 cool, thanks! 1 day ago
    • In vi, :set list to show hidden characters, to revert, :set nolist Very handy. 1 day ago
    • Team just did their first PechaKucha [ http://vurl.me/EEP ] session. I love this format and am very impressed with results! 2 days ago
    • Just posted Lauren's new 'Curry Chicken Salad' recipe to http://lowsaltlauren.com . 4 days ago
  • Categories

    classy-inheritance Code Style DataMapper Fusion git Haml Interview Questions jQuery lockdown Merb MysqlUtils Process Quick Tips REST RSpec Ruby RubyOnRails rubytrends Stage thoughts Uncategorized


  • Archives

    • November 2009
    • May 2009
    • April 2009
    • March 2009
    • February 2009
    • January 2009
    • December 2008
    • November 2008
    • October 2008
    • August 2008
    • July 2008
    • June 2008
    • May 2008
    • April 2008
    • March 2008
    • February 2008
    • January 2008
    • December 2007
    • November 2007

Blog at WordPress.com.

Theme: Mistylook by Sadish.