HomeRamblings  ⁄  GeneralProgrammingRuby Language

Ramaze and ActiveRecord

Published: February 04, 2009 (almost 9 years ago)
Updated: over 2 years ago

Thanks to the great folks on IRC over at Freenode#ramaze, I was able to not only get Ramaze working with Erubis and Activerecord for a pseudo apples to apples comparison of Rails vs. Ramaze performance benching, but I was also able to get Apache 2.2.9 talking to Passenger to Ramaze. This quick post will take you through the basics.

Environment

This post will guide you through setting up the following environment on Ubuntu Intrepid (8.10):

To get started:

sudo apt-get install apache2 passenger
sudo passenger-install-apache2-module

Install the Rack, Ramaze, Activerecord, and Erubis gems

sudo gem install rack, ramaze, activerecord, erubis

Establishing Project

Now create your first ramaze project with:

ramaze --create demo

Then change to the demo directory. If you see a start.ru file, rename it to config.ru or Passenger won’t find it. Create a file called passenger.rb with the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
require 'rubygems'
require 'ramaze'

# Add directory start.rb is in to the load path, so you can run the app from
# any other working path
$LOAD_PATH.unshift(__DIR__)

# Initialize controllers and models
require 'controller/init'
require 'model/init'

Ramaze::Global.sourcereload = false
Ramaze::Global.sessions = true
Ramaze::Log.ignored_tags = [:debug, :info]

Important: Do not include “Ramaze.start …” in this file or this will surely mess things up for Passenger. Now edit the config.ru file (formerly start.ru):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/usr/bin/env rackup
# start.ru for ramaze apps
# use thin>=0.6.3
# thin start -r start.ru
#
# rackup is a useful tool for running Rack applications, which uses the
# Rack::Builder DSL to configure middleware and build up applications easily.
#
# rackup automatically figures out the environment it is run in, and runs your
# application as FastCGI, CGI, or standalone with Mongrel or WEBrick�..all from
# the same configuration.

require 'app'
Ramaze.trait[:essentials].delete Ramaze::Adapter
Ramaze.start
run Ramaze::Adapter::Base

Add the following virtual host file to /etc/apache2/sites-enabled/001-ramaze-demo

1
2
3
4
5
6
7
<VirtualHost *:80>
    ServerName ramaze.demo.local
    RackBaseURI /
    RailsAutoDetect off
    RackAutoDetect on
    DocumentRoot /var/www/ramaze/demo/public
</VirtualHost>

And edit your /etc/hosts file to include “ramaze.demo.local” so it resolves to localhost.

Database

Next, create a database called ramaze_demo (or your choice) and add a posts table and some data via SQL or migrate scripts (this being a minimal demonstration and all that).

1
2
3
4
5
6
7
8
9
10
create table posts (
    id        int(11) not null auto_increment
  , title     varchar(255) not null
  , body      varchar(1024) not null
  , primary key (id)
);

insert posts values (1, "First Post", "Thank hrnt for getting passenger talking to ramaze.");
insert posts values (2, "Another Post", "Ask Pistos what SelfMarks is, because he is bored with diigo");
insert posts values (3, "IRC, you say?", "Visit #ramaze on Freenode");

Model

Edit the model.init.rb file with the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
require 'activerecord'
require 'cleanup_connection_patch'

  ActiveRecord::Base.establish_connection(
    :adapter  => "mysql",
    :database => "ramaze_demo",
    :host     => "localhost",
    :username => "root",
    :password => "secret"
  )

class Post < ActiveRecord::Base
end

Important: cleanup_connection_patch comes from github.com and makes the ActiveRecord behave correctly in a threaded environment. Please see Monkey patching ActiveRecord to automatically release connections « coderrr for more information.

Controller

With the model squared away, time to turn our attention to the controller. Edit controller/init.rb:

1
2
3
4
5
6
7
8
9
10
11
class Controller < Ramaze::Controller
  layout '/page'
  helper :xhtml
  engine :Erubis
end

class PostsController < Controller
  def index
    @posts = Post.find(:all)
  end
end

View

Create a folder under view for posts and add the following Erubis template view/posts.rhtml:

1
2
3
4
5
6
7
<h1>Listing Posts</h1>

<ul>
  <% for post in @posts %>
      <li><%= A(post.title, :href => "/post/#{post.id}", :title => post.body) %></li>
  <% end %>
</ul>

Note: that while Rails uses filename.html.erb, the Erubis engine expects *.rhtml extension in Ramaze.

Running

Test out the above with webrick, mongrel, or thin with:

ruby start.rb

If all goes well, you should see the three postings above listed. Launch Apache2, if you haven’t already and point your localhost’s browser at http://ramaze.demo.local/posts You should now have a listing of posts rendered through Apache via Passenger.

Conclusion

I am finding much to like about Ramaze, especially after developing with Rails for a few years now and watching it grow at an alarming rate in complexity. Ramaze is a refreshing return to basics. I am finding that Ramaze just may be able to give me most of what I need while giving me a sizeable performance boost in the process. Here’s a rails bench on the equivalent of the above:

Concurrency Level:      50
Time taken for tests:   4.277 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      10218492 bytes
HTML transferred:       9595000 bytes
Requests per second:    233.83 [#/sec] (mean)
Time per request:       213.828 [ms] (mean)
Time per request:       4.277 [ms] (mean, across all concurrent requests)
Transfer rate:          2333.42 [Kbytes/sec] received

And this is Ramaze:

Concurrency Level:      50
Time taken for tests:   2.248 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      9815000 bytes
HTML transferred:       9555000 bytes
Requests per second:    444.91 [#/sec] (mean)
Time per request:       112.383 [ms] (mean)
Time per request:       2.248 [ms] (mean, across all concurrent requests)
Transfer rate:          4264.42 [Kbytes/sec] received
comments powered by Disqus