Ruby On Rails, Design, Simplicity, Web 2.0, Ajax, Mac and Tons of Pizza.

Mar 01

Howto create a new action with a resource

Posted by Sandro Paganotti in Ruby on Rails - comments are closed digg this add to delicious

By the time I’m writing, RESTful applications are in very high position in the top chart of the best software architecture for web applications. So why not to talk about this new way of programming ? :-) In this (small) how to i just want to show you how to add a personalized action inside a scaffolded resource; ok, let’s start!

First of all we need to create a rails application, and then to configure database.yml file to match our database parameters. Once this is done just move inside your application folder and write:


ruby script/generate scaffold_resource message title:string body:string 

This simple command will generate a lot of stuff, in detail:
  • A controller named messages_controller
  • A model named message
  • A migration named xxx_create_messages
  • A view folder named message that contains all the scaffold view
  • Fixture and unit tests for the model and the controller
This command also add a line in your ‘config/routes.rb’ file:

map.resources :messages

Ok, now you have a RESTful scaffold, but what if you want to add a new action (for example a ‘read’ flag) ? It’s quite easy: first of all we need a new migration:


ruby script/generate migration read_flag

Now open xxx_read_flag.rb and add:


class ReadFlag< ActiveRecord::Migration 
  def self.up 
       add_column :messages, :read, :boolean, :default => false 
  end  
  def self.down 
       remove_column :messages, :read 
  end 
end 

Then execute rake db:migrate to synchronize your database with the current migration. Ok, these steps are not so different from the old-school way of coding, but the following will be. We’re going to map our new action inside our resource, Rails let us choose which HTTP method we want to bind with our action; one of the REST guidelines tell us that we have to map INSERT actions with a HTTP POST method, and UPDATE with PUT, so we have to add to routes.rb:


map.resources :messages, :member => { :read => :post } 

Ok, we have just set up a new url: ’/message/n;read’ where n is for the message id, now the most is done, the next steps involve the creation of a read action inside the message controller and the creation of a link (with method post) inside our list view that point to that action.


# Part 1: define the action (inside messages_controller.rb)
def read
  respond_to do |format| 
    if Message.find(params[:id]).update_attribute(:read, true) 
      format.html { redirect_to message_path } 
      format.xml { head :ok } 
    else 
      format.html { redirect_to message_path } 
      format.xml { head 500 } 
    end 
  end 
end 

# Part 2: link the action inside our list view (inside /app/views/messages/index.rhtml)
<td><%= link_to 'Show', message_path(message) %></td>
<td><%= link_to 'Edit', edit_message_path(message) %></td>
<td><%= link_to 'Destroy', message_path(message), :confirm => 'Are you sure?', :method => :delete %></td>
<td><%= link_to 'Set the read flag', read_message_path(message), :method => :post %></td>


And with these last steps we have added our read action keeping the REST model valid. If you need more informations about REST architecture i suggest you to read this pdf: RESTful Rails Development freely avaiable at b-simple-de.

Sandro.

Comments

  • Christoph Olszowka

    Posted on March 04

    Hi! "one of the REST guidelines tell us that we have to map INSERT and UPDATE actions with a HTTP POST method" - Actually, I think that UPDATES should be behind a "PUT" HTTP operation, not POST. This is the case in the standard mapping, too, where the url /messages/ is mapped with POST for create, while /messages/:id is mapped for PUT. Greetings, Christoph
  • Sandro

    Posted on March 04

    You're absolutely right Christoph, i made a mistake while typing the article. Fixed now :) Thank you.
  • bobby@hotmail.com

    Posted on March 12

    Hi! a find you site in google, it's nice! I have no own homepage... somestrangetextvista is

Post a comment

Categories:

Tags:

Powered by Mephisto, Valid XHTML 1.1, Valid CSS - Supported by Wave Factory