Peter's blog

blog about computers, science, and computer science

RSS Feed

Ruby again: Sinatra and MVC discussion

Comments Off
Posted by peter on July 30, 2012 at 10:43 pm

Although Ruby is mostly famous for Ruby-on-Rails framework, it’s not the only one existing in Ruby world.

The tutorial I mentioned before suggests Sinatra as introduction to Web development on Ruby. I gladly went into the open door, and what have I discovered…

  1. Easy to install (just another Ruby gem, duh)
  2. Not total MVC, but separates views from the logic (see my opinion below)
  3. Can be easily (!) deployed with CGI (and I love the “easy” part above all) – no tricks, no configuration to mess up, no Apache modules

Now, who said MVC is a holy cow? After all, the separation between Controllers and Model is somewhat vague (which leads to designs like MVVC), while the separation between Views and the logic is essential. When I build my CodeIgniter sites (and CI is just a “by the book” MVC), my Models are merely convenience wrappers around CI DB manipulation calls. On the other hand, MVVM and MVP patterns were born because some web apps are so DB-driven, that Controller functionality is reduced to View Model or Presenter or whatever they call it (it might be just another name to name the same thing, but it also points out that in many case generic Controller turns into something more specific and close to either the Model or the View). The bottom line it, the separation of Views is mandatory, and Sinatra provides it, and then you can play with your Models/Controllers/whatevers as it pleases you.

For the beginning, you just start your Web app with ruby <your-app-name>.rb, as if you would start a normal Ruby script. This would be your development web server. At some point, Sinatra will produce a message like this:

[2012-07-30 11:44:36] INFO  WEBrick::HTTPServer#start: pid=24851 port=4567

Now you can start some browser on local box, and go to localhost:4567 — it will display your Web app.

To stop your development server, hit Ctrl-C, and it will say:

^C
== Sinatra has ended his set (crowd applauds)

;)

You can start creating your Sinatra app like described here, but I personally would suggest you to just put together the script and the Views directory. (Simplicity, remember?)

The “Hello World” start

Let’s take a look… Eventually it’s going to be the “Borg Attack” game on the Web, hence all the names.

Here is the code:

require "sinatra"
require "erb"

module Borgattack
  get '/' do
    greeting = "Hello, World!"
    erb :index, :locals => {:greeting => greeting} 
  end
end

require “sinatra” — brings Sinatra framework, and takes care of all the web server / http stuff.

require “erb” — is for your page handling, templates etc. Higher level stuff.

Now, something that I hate: the name erb is cryptic. But after having “gems”, “bundles”, and “sinatra” itself, it’s not a big deal to complain about, indeed. :)

Here is something that I love though: that line

erb :index, :locals => {:greeting => greeting}

is easy, understandable, transparent by all means. We call that erb thing (whatever it is, it separates views from the logic), it should load the index with the dictionary of variables which are processed in your View (the latter is standard technique in CI, Django, ASP.NET — probably in in every Web development framework).

A View is a template. (Hmm, here is another prove the separation of Views is essential: templates became popular long before the MVC pattern. Ever heard of PHP Smarty?) And Sinatra Views templates have their syntax (template code comes almost entirely from Zed Shaw’s example):

<html>
  <head>
    <title>Star Trek -- Attack of the Borg</title>
  </head>
  <body>
    <% if greeting %>
      <p>I just wanted to say <em style="color: green; font-size: 2em;"><%= greeting %></em>.
    <% else %>
      <em>Hello</em>, world!
    <% end %>
  </body>
</html>

So, again, we have some typical template language inside HTML files. It’s standard technique, and therefore it’s easy! Zero learning curve! If you are familiar with this stuff in general, you can start developing web sites using this Sinatra thing almost immediately!

Handling Forms – easy!

Next cool thing in Sinatra: forms. They’re probably done in most elegant way in Sinatra than I’ve ever seen anywhere. Here is how it works:

  • define “get” method for the form => will show your form.
  • define “post” method => handles the submitted form. params dictionary handles the submitted parameters / filled-up fields

That’s it! OMG, literally — that’s it! You can do forms in Sinatra now!

E.g

  get '/hello' do
    erb :hello
  end

  post '/hello' do
    greet = params[:greet] || "Hello"
    name = params[:name] || "Nobody"
    erb :index, :locals => {:greeting => "#{greet}, #{name}"}
  end

So easy, so good!

You can concentrate now on the task at hand, rather than on “learning the framework” overhead.

Templates

Again, it’s really easy! Most simple websites use just one template for all pages. You just put another file to the Views directory, named layout.erb, and it will be picked up by default.

layout.erb code:

<html>
  <head>
    <title>Star Trek -- Attack of the Borg</title>
  </head>
  <body>
  <h1>Star Trek -- Attack of the Borg</h1>
  <%= yield %>
  </body>
</html>

Then you can strip down your pages of the header and footer part. E.g. your index page:

<p><a href="/hello">Say Hello</a></p>

<% if greeting %>
  <p>I just wanted to say <em style="color: green; font-size: 2em;"><%= greeting %></em>.
<% else %>
  <em>Hello</em>, world!
<% end %>

I have to admit, I’m totally ecstatic, indeed! The code appears to be much more concise than even I have in CI. You might seriously consider Sinatra for small, non-static website development. In other words, it seems to be a good competitor for CodeIgniter.

Both comments and pings are currently closed.