Rails 3 Routing with Rack

Sun Feb 07 05:56:12 -0800 2010

You probably all have heard that “Rails lets you route to Rack applications directly” and thought “Oh really?” well… bet you didn’t think it would be this simple.

Rails 3 really opens up a whole new world of pluggable awesomeness. This post expects you have already installed Rails 3 —prerelease, if not, follow the instructions in the Release Notes

The goal here is to make a Sinatra app run inside of Rails, taking routes it needs directly using the new Rails routing features.

Code is better at talking than me, so first make a new app:

$ rails app

Let rails do its thing. Then we want to make a simple Sinatra app, let’s make it marginally useful and have it hit Twitter.

Make a directory lib/twitter and in there make a new file called twitter_app.rb, inside of it put:

class TwitterApp < Sinatra::Base
  set :root, File.dirname(__FILE__)

  get '/twitter' do
    @user = 'raasdnil'
    t = Twitter::Search.new(@user).fetch
    @tweets = t.results
    erb :twitter
  end

end

This is a basic Sinatra app, it first sets its root directory to be the directory of the current file (needed because using the Rails root will not work) and then responds to one url /twitter that uses the Twitter gem to do the heavy lifting on searching for all the tweets by some weirdo (me).

It then assigns all the tweets to an instance variable and renders the template twitter.erb.

We have to make this template, so create another folder lib/twitter/views and make a file in there called twitter.erb and put in the following:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Tweets mentioning <%= @user %></title>
  </head>
  <style type="text/css" media="screen">
    div.tweet { border: 1px solid gray;
                height: 50px;
                width: 600px;
                padding: 5px;
                margin-bottom: 10px; }
    img.icon { float: left; padding-right: 10px; }
    div.text { font-family: verdana, sans-serif; }
    div.<%= @user %> { background: #F4F4FF; }
  </style>
  <body>
    <% @tweets.each do |tweet| %>
    <div class="tweet  <%= tweet.from_user %>" id="<%= tweet.id %>">
      <img class="icon" src="<%= tweet.profile_image_url %>" />
      <div class="text" >
        <%= tweet.text %>
      </div>
    </div>
    <% end %>
  </body>
</html>

OK, our Sinatra app is ready to fire. Now hooking it up is simple.

First, we need to make sure we require the needed gems, so open up your Gemfile in Rails root and add the following:

## Bundle the gems you use:
gem "sinatra", "0.9.2"
gem "twitter", "0.8.3"

Then do a bundle check to make sure we have the gems we need:

$ bundle check
The Gemfile's dependencies are satisfied

All good (if that gave you an error, just run bundle install).

Now the final step is to wire up the Rails Router.

Open up config/routes.rb and add a require for your twitter app as well as a route to match ‘/twitter’ and send to your Sinatra App, something like this:

require 'twitter/twitter_app'

RackTest::Application.routes.draw do |map|

  match '/twitter', :to => TwitterApp

end

And that’s it!

Fire up your Rails app with rails s as you normally would, and browse to http://127.0.0.1:3000/twitter and proove it to yourself… this stuff works.

Almost too simple.

blogLater

Mikel

  1. Dan Croak Says:

    Why lib/twitter.rb? I’ve been placing Sinatra apps in app/metal in Rails 2.

    Also, I’m just learning HTML5 but can’t that xmlns attribute be removed? Looks like you’re mixing the HTML5 DOCTYPE with XHTML stiff.

  2. Rymaï Says:

    Awesome! Thanks!

  3. Matt Says:

    The xmlns attribute is indeed a remnant of XHTML, but it’s not incorrect to include it: http://diveintohtml5.org/semantics.html

  4. Mikel Lindsaar Says:

    Thanks Matt, handled it.

  5. Mikel Lindsaar Says:

    @dan because sinatra is not Rails metal and this shows an example of using a separate application within your rails app, as it is not part of your app, it makes sense for it to be in lib.

    The idea being, you could put this app in any rails app and with two lines of code include it.

    Mikel

  6. Marcelo Silveira Says:

    Definitely too simple. Thanks.

  7. jc Says:

    Shouldnt the sinatra app be get “/” instead of get “/twitter”?

  8. mark Says:

    All kinds of and everything about metal rack,Thank you for visiting our site.http://www.metaldisplayrack.com/sheet-metal_rack.htm

  9. Brian Armstrong Says:

    Lol…that poor spammer in the previous comment thought you were talking about actual sheet metal!

  10. chideleou Says:

    This was a fantastic post. Really loved reading your weblog post. The information was very informative and helpful.

  11. Mikel Lindsaar Says:

    @Brian, nice…. I think I will leave it there for prosperity / stupidity value :)

  12. Adam Says:

    Thanks for the informative post. I’ve gotten almost everything working nicely but I can’t figure out how to serve static content. I have stylesheet.css in the public folder and I’m not sure how to access it when running the Sinatra app inside a Rails 3 app. Any ideas?

  13. Luis Says:

    @Adam

    Couldn’t you do something like:
    dir = File.dirname(File.expand_path(FILE))
    set :public, “#{dir}/public”

  14. christmas cards Says:

    Your post is really good and informative. I’m surprised that your post has not gotten any good quality, genuine comments. You have done a great job by posting this article.

  15. christmas cards Says:

    I’ve gotten almost everything working nicely but I can’t figure out how to serve static content. Thanks for the informative post.

  16. minoterie Says:

    The person who shaped this post is a genius and knows how to keep the readers joined.Thanks for giving out this with us. I found it informative and interesting.
    moulin farine

  17. no fee debit dc Says:

    The scoop here is to makes a Sinatra app run inside of Rails, transference path it needs directly using the new Rails routing features.

  18. ScotWetherington Says:

    Very informative and inspiring. Thanks for sharing.

  19. Poultry Feed Mill Equipment Says:
    I’ve gotten almost everything working nicely but I can’t figure out how to serve static content. Thanks for the informative post.
  20. online repair manual Says:

    hey thanks for throwin up this quick guide. I have been STRUGGLING with my rails app, and this really saved me some time. Thanks again.

  21. Toronto Internet Marketing Says:

    Nice! Really helpful post!
    Rails 3 is really awesome!

  22. TenlyR. Says:

    I love that “Rails lets you route to Rack applications directly”! This has simplified my job so much! It is amazing the time savings that this has given me. It has been so simple to implement and set up using cloud computing. It has been a great way to create and use new plugins. I’m loving everything about it!

  23. custom OLED displays Says:

    class TwitterApp < Sinatra::Base
    "set :root, File.dirname(FILE)

    get ‘/twitter’ do @user = ‘raasdnil’ t = Twitter::Search.new(@user).fetch @tweets = t.results erb :twitter end

    end"

    I am having problems witha tha piece of code, the basic Sinatra app, are you guys facing problems or can you run it well?

  24. Peanut Machine Says:

    This was a fantastic post. Really loved reading your weblog post. The information was very informative and helpful.

  25. mazapoint Says:

    this is really nice post and i like this post

  26. slub yarn in pakistan Says:

    You probably all have heard that “Rails lets you route to Rack applications directly” and thought “Oh really?” well… bet you didn’t think it would be this simple.

  27. Demotivational Posters Says:

    I’ve gotten almost everything working nicely but I can’t figure out how to serve static content. I have stylesheet.css in the public folder and I’m not sure how to access it when running the Sinatra app inside a Rails 3 app.

  28. free cell phone spy Says:

    Thanks for sharing this great article ! I feel strongly about it and love learning more on this topic. It is extremely helpful for me. I hope you post again soon

  29. Ios On Android Phone Says:

    This was a fantastic post. Really loved reading your weblog post. The information was very informative and helpful.

  30. Ios On Android Phone Says:

    This was a fantastic post. Really loved reading your weblog post. The information was very informative and helpful.

  31. jibran Says:

    The best person to give you medical advice about liver disease is your doctor. Best thing we can do is recommend perhaps a good doctor if you need a second or third opinion. casino

  32. mazapoint Says:

    Rails 3 real opens up a full new class of pluggable awesomeness. This transfer expects you individual already installed Rails 3 -prerelease, if not, simulate the instructions in the Announcement Notes

Leave a Reply