Build an app with Ruby on Rails resources
Resources have been introduced in Rails 1.2. Basically this allows your application to expose content in different formats. Normal users with browsers get a nice HTML page while applications get easy to use XML code. Besides that Rails implements HTTP requests as GET, POST, PUT and DELETE.
All well, but how can you put this to your advantage when developing a Ruby on Rails application?
This article shows you how you can use Rails Resources as building blocks for your application. Let’s say you need to develop a simple portal application with news items and events. The news should have focus on the frontpage, but events should also be accessable on the frontpage.
Before I do anything more, I’ll create the a new rails project and use an sqlite3 database for ease of use.
$ rails --database=sqlite3 portal
Creating the building blocks
To start with the news I generate a scaffold_resource named article. This will give me an articles controller and an article model. This is the first building block.
$ ./script/generate scaffold_resource article title:string body:text
Before you migrate your database, edit the migration in db/migrations/001_create_articles.rb:
class CreateArticles false, :default => "", :limit => 100
t.column :body, :text, :null => false, :default => ""
t.column :created_at, :datetime
t.column :updated_at, :datetime
end
end
def self.down
drop_table :articles
end
end
Next we create the second block named ‘event’.
$ ./script/generate scaffold_resource event title:string happens_on:date description:text
and the migration is edited to look like this:
class CreateEvents false, :limit => 100, :default => ""
t.column :happens_on, :date, :null => false
t.column :description, :text, :null => false, :default => ""
t.column :created_at, :datetime
t.column :updated_at, :datetime
end
end
def self.down
drop_table :events
end
end
Migrate your database next:
$ rake db:migrate
You may now start your webserver and enjoy all the scaffold goodness. You can CRUD articles and events now! Everything is still in scaffold from, but it’s a good start.
Adding some routing magic
You’ll never display all news items on your frontpage. You probably want the ten latest items and the newest first. For this to integrate nicely with the article resource we’ll add a new route and a simple method to the articles controller.
In app/controllers/articles_controller.rb add the following method:
def latest
@articles = Article.find(:all, :limit => 10, :order => "created_at DESC")
respond_to do |format|
format.html # latest.rhtml
format.xml { render :xml => @articles.to_xml }
end
end
and in config/routes.rb you should replace
map.resources :articles
with
map.resources :articles,
:collection => {
:latest => :get
}
You may also want to create a file named app/views/articles/latest.rhtml. This may, for now, be a copy of app/views/articles/index.rhtml.
Now you can access http://localhost:3000/articles;latest to get the ten latest articles, newest first.
Let’s do the same for events, but in this case we want the five next events in our database.
app/controllers/events_controller.rb:
def upcoming
@events = Event.find(:all, :limit => 5, :order => "happens_on", :conditions => ['happens_on >= ?', Time.now])
respond_to do |format|
format.html # upcoming.rhtml
format.xml { render :xml => @events.to_xml }
end
end
config/routes.rb:
map.resources :events,
:collection => {
:upcoming => :get
}
Again, copy app/views/events/index.rhtml to app/views/events/upcoming.rhtml for now. http://localhost:3000/events;upcoming now shows the next five events that are going to happen.
Make things more sexy
Okay, now let’s spice up the latest.rhtml and upcoming.rhtml views. You may copy/paste the following:
app/views/articles/latest.rhtml:
Latest articles
app/views/articles/upcoming.rhtml:
Upcoming events
- —
This will make those special collections look a bit nicer.
Putting it all together
Now you have your building blocks ready, start building! I prefer to create a special controller that handles special pages like the frontpage.
$ ./script/generate controller pagemill
Add a simple method to the controller to show a frontpage. All the magic will happen in the view, so you controller basically looks like this:
class PagemillController
Now create a file app/views/pagemill/frontpage.rhtml
< %= render_component :controller => 'events', :action => 'upcoming' %>
Portal Frontpage
Some standard talk about this portal goes here.
< %= render_component :controller => ‘articles’, :action => ‘latest’ %>
Only two things to do, first remove the default public/index.html
$ rm pubic/index.html
and add a default route in config/routes.rb
map.connect '', :controller => "pagemill", :action => "frontpage"
Enjoy your hard work
You can now enjoy your hard work by surfing to http://localhost:3000.
What's next?
There’s still a lot to do:
- Add some more style and colours (use the CSS, Luke)
- Change the templates I specified here to suit your needs.
- Include additional information for your articles and events.
- Change the templates when viewing an article or event.
- Add some basic navigation
- Protect your site by adding users and permissions
Too lazy to copy/paste?
You may download this rails project. I’ve used Rails 1.2.2 on Mac OS X and SQlite3. Of course you can use other databases like MySQL if you like.