Archive for the 'Ruby' Category


Typo Sidebar Tutorial

Wednesday, March 8th, 2006

I’ve been playing around a bit with Typo, a Rails blogging program, recently. The main reason I chose Typo is because I wanted to add some news features to a golf league manager I’ve also written in Rails. Merging the two code bases is probably a bit much at this stage but I did want to add something to Typo to integrate the two. The best way to do is sidebar components. This is a brief tutorial on how to write a sidebar component. In my examples I’ll use the category sidebar from Typo.

Read the rest of this entry »

Spread the word: Technorati related  |  del.icio.us bookmark it!  |  submit Typo Sidebar Tutorial digg.com digg it!  |  reddit reddit!

Does logic belong in the database?

Tuesday, February 14th, 2006

Builder UK has done an indepth interview with David Heinemeier Hansson, Ruby on Rails: The importance of being 1.0. I like Rails and would like to use it more, but was never very happy with it’s lack of SQL features. From the interview:

Regarding the specifics, it’s no secret that I’m not a big fan of logic in the database. I don’t think the database is an appropriate place to maintain a coherent domain model. And I don’t think you should integrate multiple applications through the database. So if you follow that and shield your database from access of multiple applications, you can move all of that logic you would have put in stored procedures, triggers, and what have you into an object-oriented model that can take advantage of the last 20-plus years of progress in software-development techniques.

There’s a fair point but in the past I’m pretty sure DHH mentioned foreign keys were unnecessary too, which I found frustrating when I switched from PostgreSQL to MySQL (DreamHost doesn’t support the former).

But now I look back at it, it doesn’t look bad. Rails has several features that makes it possible to maintain data integrity and allows you to keep all the details of your model in one place, e.g. hasmany, belongsto in ActiveRecord. Also Rails apps tend to be built from the ground up (rather than built on top of legacy systems) so if you control the only access points to the database, why not limit your checks to one place? There are two things that come to mind that made me think keeping all the data integrity in the source code was a bad thing.

ACS 4.0 Tcl My first real programming job was at ArsDigita. They had a toolkit know as the ACS (ArsDigita Community System), which at the time was written in Tcl. Tcl is a scriping language, a fairly simple one at that. One of the big new features in ACS 4 was object orientation. I can’t remember how they did OO in Tcl but I do recall the extends they went to to mimic OO features in the database. Object hierarchies were modelled by table hierarchies, with lots of constraints, we even wrote OO data retrieval functions in Oracle PL/SQL. Beyond that there was also a lot of emphasis on reducing the amount of SQL queries each web page makes and optimizing them where ever possible. If you’re interested, here’s the full indoctrination.

JDBC The other thing I’m going to blame is how hard it is to do SQL in Java. It’s just painful. How verbose is this!

Connection c = ... // I won't bother including connection setup code
PreparedStatement ps = null;
ResultSet rs = null;

try {
    ps = c.prepareStatement("select id, name, password from users where id = ?");
    ps.setString(1, id);
    rs = ps.executeQuery();

    if (rs.next()) {
        String id = rs.getString(1);
        String name = rs.getString(2);
        String password = rs.getString(3);

        User user = new User(id, name, password);
        return user;
    }
} 
finally {
    // I won't bother with closing code either
    close(rs);
    close(ps);
}

With Rails you declare your User class as:

class User < ActiveRecord::Base

end

and the lookup code is:

user = User.find(id)

and you’re done. True the ActiveRecord limits you to fairly simple object models, but when the framework makes your life this easy, you can cope. My main point is using SQL in Java is painful enough I’d push as much logic as I can down into the database in the form of constraints, cascades, triggers, PL/SQL, etc. so I could simplify my JDBC code.

So does logic belong in the database? Yes and no. If you think your database is going to out live your application, then it’s probably a good idea to make sure it contains all your data integrity rules. But that’s not always the case, sometimes the database is just a store that’s meaningless without your application, so why duplicate logic? Rails is full of ‘it really doesn’t have to be that hard’ moments. I’m surprised I’m still coming across them.

Spread the word: Technorati related  |  del.icio.us bookmark it!  |  submit Does logic belong in the database? digg.com digg it!  |  reddit reddit!

Scratch that FastCGI IPC bit

Saturday, August 6th, 2005

In amongst what I did in the last post I did a few other things. One was installing the ‘fcgi’ gem and trying to not use ‘fcgi_hander’ and require the gem instead. This didn’t work because I left in the ‘RailsFCGIHandler.process!’ bit and didn’t copy over the old Dispatcher.process routine.

It was installing the ‘fcgi’ gem that fixed the Apache problem, nothing to do with the configuration. The very first line of

/usr/lib/ruby/gems/1.8/gems/rails-0.13.1/lib/fcgi_handler.rb

is

require ‘fcgi’

which is a bit of a give away. Odd that the I don’t remember seeing this error message:

[Sat Aug 06 17:49:36 2005] [warn] FastCGI: server "/.../rails-app/public/dispatch.fcgi" restarted (pid 14287) /usr/lib/ruby/siteruby/1.8/rubygems/customrequire.rb:21:in require__': No such file to load -- fcgi (MissingSourceFile) from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:inrequire’ from /usr/lib/ruby/gems/1.8/gems/activesupport-1.1.1/lib/activesupport/dependencies.rb:200:in require' from /usr/lib/ruby/gems/1.8/gems/rails-0.13.1/lib/fcgi_handler.rb:1 from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:inrequire‘ from /usr/lib/ruby/siteruby/1.8/rubygems/custom_require.rb:27:in require' from /usr/lib/ruby/gems/1.8/gems/activesupport-1.1.1/lib/active_support/dependencies.rb:20 0:inrequire’ from /…/rails-app/public/dispatch.fcgi:22

A quick check on DreamHost (gem list –local | grep fgci) shows they haven’t got it installed either. Good thing I didn’t submit that ticket yet!

Spread the word: Technorati related  |  del.icio.us bookmark it!  |  submit Scratch that FastCGI IPC bit digg.com digg it!  |  reddit reddit!

Upgrading to Rails 0.13.1 pains

Saturday, August 6th, 2005

Dreamhost has upgraded to Rails 0.13.1, so I figured I should too. The actual application upgrade was simple enough, the main tricky part of figuring out which files I should just ditch and replace with new copies. ‘config/environment.rb’ was probably the only one.

I did the upgrade locally and it worked fine on WEBrick. Things didn’t go as smoothly when I upgraded it on the server, first there were stupid things like forgetting to make ‘production’ the default Rails environment again (overwriting environment.rb will do that). But the more serious problem of the site timing out. I came across this my Apache error log:

[Sat Aug 6 08:51:48 2005] [error] [client x.x.x.x] FastCGI: comm with (dynamic) server "/home/xxx/yyy/public/dispatch.fcgi" aborted: (first read) idle timeout (240 sec) [Sat Aug 6 08:51:48 2005] [error] [client x.x.x.x] FastCGI: incomplete headers (0 bytes) received from server "/home/xxx/yyy/public/dispatch.fcgi"

Not a good sign, and not obvious what’s causing the problem. At this point I figured I better put the old version back (copied the backup over rather than any fancy CVS tricks). To avoid future downtime I setup another domain to act as a staging server. This means I can test upgrades on an identical setup as the live server. But of course DNS updates take time so I didn’t have access to it straight away.

Rather than wait, I figured I’d just install Apache/FastCGI locally. Should be fairly straightforward, but these things never are. I followed this guide:

http://wiki.rubyonrails.com/rails/show/HowtoInstallOnGentooWithApache

Straightforward enough but I kept getting 403 errors when I tried to access the site. I thought it was some weird Apache access error and spent forever looking at the Deny and Allow settings in the config files. After a lot of wasted time I realised while the app directory was set to 755, my home directory was set to 700, doh!

So once that was fixed I could access the site and get the same timeout problem as I did on the live copy. Googling the FastCGI error message turned up a lot of red herrings but I eventually came across a post saying it might be a permissions problem with the interprocess communication file (IPC) that FastCGI uses. I quick check in my commonapache2.conf file showed this wasn’t set anywhere, so I threw this in the end: <ifmodule modfastcgi.c> FastCgiIpcDir /tmp/fcgiipc FastCgiServer /…/rails-app/public/dispatch.fcgi -initial-env RAILS_ENV=production -processes 15 -idle-timeout 60 </ifmodule>

Voila! It now loaded but crashed with a MySQL error:

HY000Host ‘x.x.x.x’ is not allowed to connect to this MySQL server

which was very confusing since ‘x.x.x.x’ was my external IP, not the IP of my laptop. I first thought MySQL must be setup to only accept connections from localhost. But digging around the config files didn’t turn up anything that looked like per-host access/deny. This is because connections from different hosts are setup on a per user basis, not a per server basis. This makes sense, but is different from other servers I configured, so it took a while to find this out. With the new fancy user setup it still failed with the same message. After a lot of head banging I realised it’s connecting to the production database not the development one! Hacking my database.yml proved this to be correct.

I finally had a working Apache/FastCGI setup, and confirmed a fix is setting up the FastCGI IPC file. It looks like the root of the problem is the switch to RailsFCGIHandler in dispatch.fcgi, which no longer works with the old Apache setup. But of course it’s set in the Apache config file, which I have no control over on DreamHost, time to raise a ticket!

Spread the word: Technorati related  |  del.icio.us bookmark it!  |  submit Upgrading to Rails 0.13.1 pains digg.com digg it!  |  reddit reddit!

Native Rails/FastCGI on DreamHost!

Saturday, June 18th, 2005

DreamHost has unofficially started to support Ruby on Rails and FastCGI. There’s been a thread on their programming discussion board about this and someone from DH said FastCGI is now available but they haven’t made a formal announcement yet. Setting up things is pretty straightforward. In the DreamHost Control Panel select ‘Domains > Web’ and choose to edit ‘http’ on the domain you want to use Rails with. Then tick ‘FastCGI Support?’ and make you web directory point to the ‘public’ sub-directory in your Rails project directory.

The next step is to edit ‘.htaccess’ in ‘public’. Change RewriteBase to ‘/dispatch.fcgi’ and alter the last ReWrite rule so it also points to dispatch.fcgi. That’s it your Rails app should now run. If you were running off your own copy of Ruby (like I was) remember to change where your dispatch.fcgi finds Ruby (change the first line).

I also noticed that the value in ‘RAILS_ENV’ wasn’t getting picked up so I altered config/environment.rb to use the production, instead of the development environment by default.

Spread the word: Technorati related  |  del.icio.us bookmark it!  |  submit Native Rails/FastCGI on DreamHost! digg.com digg it!  |  reddit reddit!

Packets out of order: 1<>3

Tuesday, May 31st, 2005

So what does Packets out of order: 1<>3: mean when in shows up in your Rails log? It means DreamHost has upgraded to MySQL 4.1.x, which has a new password hashing technique, but you’re still using the old one, and the pure Ruby MySQL driver only has support for the new one.

Basically Rails can no longer connect to MySQL because it’s failing on the password authentication. There are a few fixes, the easiest would be to update your passwords for MySQL 4.1 but I can’t do this on DreamHost because you don’t have permissions when logging in via console and the web interface only creates the old style ones. The other way is to install the C bindings for the MySQL driver, which does support the old password style:

gem install mysql

It also looks like DreamHost is getting closer to supporting Ruby on Rails. They’ve installed a copy of Ruby 1.8.x and testing FastCGI internally. Hopefully this means I won’t have to manage my own install for much longer!

Spread the word: Technorati related  |  del.icio.us bookmark it!  |  submit Packets out of order: 1<>3 digg.com digg it!  |  reddit reddit!

At least Ruby makes things easy

Wednesday, March 23rd, 2005
def before_destroy 
    scores.each { |x| x.destroy }
end

A lot easier than deleting related objects in Java!

Spread the word: Technorati related  |  del.icio.us bookmark it!  |  submit At least Ruby makes things easy digg.com digg it!  |  reddit reddit!

I want PostgreSQL back!

Wednesday, March 23rd, 2005

DreamHost doesn’t support PostgreSQL. That’s fine, a lot of people use MySQL, so it can’t be that bad. But by default MySQL doesn’t support foreign keys, you need to enable InnoDB for that. And surprise, surprise DreamHost doesn’t current support InnoDB. So instead of a few carefully placed ‘ON DELETE CASCADE’s, I have to manually delete all related objects in my Ruby code. What a PITA, bring back PostgreSQL!

Spread the word: Technorati related  |  del.icio.us bookmark it!  |  submit I want PostgreSQL back! digg.com digg it!  |  reddit reddit!

Installing Ruby on Rails on DreamHost

Tuesday, March 22nd, 2005

After initially deciding to try TextDrive I eventually opted for DreamHost because it looks like they are going to offer better long term stability. But DreamHost doesn’t support Rails natively, and aren’t planning to until it gets into Debian’s stable release, so sometime in 2010. But it’s a pretty flexible host so you can run your own software. I came across this guide for installing Rails on DreamHost:

http://www.numberporn.com/archives/000118.php

Unfortunately, it already appears to be out of date, and the last Apache configuration doesn’t work with the current version of Rails. But that’s just a minor blip because each request reloaded the entire Rails framework, so I doubt it would have been usable.

I decided to give up trying to get it to run inside Apache and just use the WEBrick server that comes bundled with Rails. First startup the server (from the root of your Rails application):

nohup script/server -e production &> log/WEBrick.log &

At this point you should exit your ssh session then relogin because if the ssh session times out it’ll take WEBrick with it, but exiting means nohup will keep it alive.

The next step is to get Apache to forward to WEBrick. In the ‘.htaccess’ file in your web directory, enter:

RewriteEngine On
RewriteCond   %{SERVER_PORT}  ^80$
RewriteRule ^(.*)$ http://www.yourhomename.com:WEBRICK_PORT/$1 [L]

Replacing yourhomename and WEBRICK_PORT with the actual values. This makes Apache redirect all requests to WEBrick. The only annoying thing is it displays the port number in the rewritten URL. This is fine for toy applications, but not good enough for production applications. In theory replacing [L] with [P] is supposed to mask this by making Apache act as a proxy, but it returns a 404 instead. Everything I learnt about Apache configuration I learnt in the past hour, so there’s a good chance I’m doing something wrong.

But anyway that gets your Rails app running on your DreamHost account, which is a definite step forward.

Spread the word: Technorati related  |  del.icio.us bookmark it!  |  submit Installing Ruby on Rails on DreamHost digg.com digg it!  |  reddit reddit!

Static typing isn’t so bad

Thursday, March 17th, 2005

So I’ve spent the past week or so putting together a simple Rails application. For the most part I’m impressed, but it’s clear it only 0.10 for a reason. I developed the app using PostgreSQL, which has a native boolean type (non standard of course), which ActiveRecord translates nicely. My web host does not have PostgreSQL installed, but the more popular MySQL.

So I installed MySQL locally and ported things over. It’s things like setting up users and permissions that bugged me the most because Google couldn’t turn up anything useful. The actual port was trivial, things like changing serial to MySQL’s auto increment thing. That is until I found MySQL doesn’t have a native boolean type, it’s just an alias for TINYINT(1). And no matter what this ticket says, they aren’t recognized properly as booleans by ActiveRecord and are treated like ints. So where before the framework did things like translating a checkbox’s default value of ‘on’ to true, I now had a bunch of silent failures.

This is where static typing is nice. It would tell me that ‘on’ is a string and not the boolean value TRUE. Things like ‘if @user.enabled then’ would fail because enabled is an int not a bool. But instead it just runs with incorrect behaviour. Thankfully there weren’t that many things I had to track down.

So this round goes to static typing. Eventually I’ll start seeing an upside to dynamic typing, but at the moment the years of Java programming still make me want to declare every little thing.

Spread the word: Technorati related  |  del.icio.us bookmark it!  |  submit Static typing isn’t so bad digg.com digg it!  |  reddit reddit!