01.30.08

Dragged Onto the Train Kicking and Screaming: Rails 2.0

The rails team recently released version 2.0 as many of you know, and in it are a lot of neat features and simplifications. Having been developing RESTful applications for the better part of the last year I welcome the new integration, but when 2.0 dropped I was mid-project on a few different apps and didn't want to deal with upgrading. Well, as luck would have it, after a day of banging my head against the wall I ended up having to stick with Rails 2.0 on my new mediatemple (dv) server account, forcing me to make my apps 2.0+ compliant.

 

As it turns out, however, this wasn't as hard as I had thought it would be. In fact, the new routes, especially for nested resources, are not only more functional and simple, but dare I say they are somewhat beautiful. Because I've been using nested resources in some of my apps, my first order of business was to find out how it is handled in the new Rails. After some brief searching I ran across an extremely helpful screencast over at rubyplus.org which you can find here.

 

I've been working on a content management system that I plan to implement on a number of projects both past and up and coming and the whole thing is completely RESTful with all sorts of AJAX goodness in it, but all decidedly Rails 1.2.6. Having been faced with the 2.0 requirement, here are a few of the things I learned along the way while transitioning to Rails 2.0; hopefully it alleviates the pain some people may go through while doing the same. First off, and most importantly for me, nested resources are handled quite differently. Before you might define the route as such:

 

map.resources :categories do |category|  category.resources :pages end

You can now define it as:

map.resources :categories, :has_many => :pages

Additionally, when creating a rake file, one mustn't need to define a category_id column for their Page class; this is handled thusly:

class CreatePages < ActiveRecord::Migration  def self.up   create_table :pages do |t|    t.string :title    t.text :content    t.references :category    t.timestamps   end  end

This will automatically add the proper id columns to your object class. Notice that time-stamps are now included by default, a very handy feature considering how many times I've had to add them to objects in the past as an afterthought. So as you might imagine, the path helpers have changed as a result too. Before, one would have used

 

<%= link_to 'Edit', edit_page_url(:id => page, :category_id => page.category) %>

when now all one needs to use is

<%= link_to 'Edit', [:edit, page.category, page] %>

in fact, here are all the routes for the nested Page resource:

category_pages GET /categories/:category_id/pages {:action=>"index", :controller=>"pages"}
formatted_category_pages GET /categories/:category_id/pages.:format {:action=>"index", :controller=>"pages"}
POST /categories/:category_id/pages {:action=>"create", :controller=>"pages"}
POST /categories/:category_id/pages.:format {:action=>"create", :controller=>"pages"}
new_category_page GET /categories/:category_id/pages/new {:action=>"new", :controller=>"pages"}
formatted_new_category_page GET /categories/:category_id/pages/new.:format {:action=>"new", :controller=>"pages"}
edit_category_page GET /categories/:category_id/pages/:id/edit {:action=>"edit", :controller=>"pages"}
formatted_edit_category_page GET /categories/:category_id/pages/:id/edit.:format {:action=>"edit", :controller=>"pages"}
category_page GET /categories/:category_id/pages/:id {:action=>"show", :controller=>"pages"}
formatted_category_page GET /categories/:category_id/pages/:id.:format {:action=>"show", :controller=>"pages"}
PUT /categories/:category_id/pages/:id {:action=>"update", :controller=>"pages"}
PUT /categories/:category_id/pages/:id.:format {:action=>"update", :controller=>"pages"}
DELETE /categories/:category_id/pages/:id {:action=>"destroy", :controller=>"pages"}
DELETE /categories/:category_id/pages/:id.:format {:action=>"destroy", :controller=>"pages"}

Forms are generated much more intuitive to in this scenario. Before I was using this bit of code to generated a form for a nested resource:

<% form_for(:page, :url => pages_path) do |f| %>

as opposed to

<% form_for([@category, @page]) do |f| %>

I of course was also faced with the removal of the edit_in_place_for helper that had been removed in favor of an optional plugin scenario. The fix for this was relatively painless however. Simply go to the route of your application and run svn export http://svn.rubyonrails.org/rails/plugins/in_place_editing One final note to mention: my editor of choice, Textmate, doesn't seem to recognize the html.erb files automatically generated by the new rails scaffolding, so all my clever little keyboard shortcuts for Ruby specific code don't work in them.

 

If anyone knows a way to configure textmate to recognize this file type I'd love to know. Anyways, here I am, firmly planted in the Rails 2.0 world and so far liking it. There's still much to learn and the documentation is a bit sparse but I'm sure all the old mainstay rails books will eventually be patched to accommodate for the changes. My hat goes off to the Rails core team for keeping the latest update simple and sticking to the core principles of the framework (and making my life simpler in the process). See you all at Railsconf 2008!



Subscribe to Just a Nutter RSS Feed

Comment_button_spacer

Current Projects

Area Studios

My web development company and project incubator. We’re always looking for interesting projects. Stop by and check out our work.

View Now

oqodo.com

Oqodo started as a mini competition between a friend and myself to build an app for our friends to keep in touch. It will soon grow into something much bigger.

View Now

My Web Presence

Flickr
Facebook
Digg
Lastfm
Linkedin
Twitter
Basecamp