Rails without ActiveRecord

Posted by Doug Wed, 08 Aug 2007 13:02:00 GMT

It’s supposed to be easy to turn off ActiveRecord and have a database-less app. The word is it’s possible in rails 1.1.x, but not with vanilla rails 1.2.x. To get your environment to load with rails 1.2, you still need a database.yml and the database created (even though it can be empty). That seems a bit silly to me. If you want a database-less app, you don’t want to have to create a database and maintain a connection to that database. There’s two problems I’ve worked around to get a true database-less app with rails 1.2.

Theoretically all you have to do is set

Rails::Initializer.run do |config|
  config.frameworks -= [:active_record]
end

The first problem is whiny nil requires ActiveRecord. By default config.whiny_nils is set to false. However, both config/environments/development.rb and config/environments/test.rb both explicitly set it to true. What I did was just comment out those assignments in the respective files. Besides detecting when you call ActiveRecord methods on nil, whiny_nil will also detect when you call Array methods on nil. By turning off whiny_nil, you loose the ability to easily detect when you’re treating nil like an Array.

The second problem is that the Rails initializer requires AcriveRecord to load the observers. This is documented in ticket #6795 on the Rails trac. It seems a bit kludgy, but what I did was redefine the load_observers method before I run the initializer in my environment.rb:

require File.join(File.dirname(__FILE__), 'boot')

module Rails
  class Initializer
    def load_observers
      ActiveRecord::Base.instantiate_observers if 
          configuration.frameworks.include?(:active_record)
    end
  end
end

Rails::Initializer.run do |config|
...

There are several reasons for wanting a database-less rails app. The ticket above references using something like CVS or Subversion as a datastore and using rails’ ActionPack to drive an interface. I’ll get into my own uses in another post soon.

Posted in  | 1 comment

RubyConf 2006

Posted by Doug Fri, 20 Oct 2006 14:52:16 GMT

Doug Alcorn I’m here in Denver for RubyConf 2006. Most of the people I only know online. So I’m walking around introducing myself to various folks. Some I already knew and some are new. I wanted to make a point of speaking to Nathaniel Talbot. I saw him at breakfast and walked over to re-introduce myself. There were a couple other guys there with him whom I also introduced myself. One of them introduced himself simply as “Matz”. Pause. Click. “Oh, hey! Thanks, man.”

BTW, if you can hear my voice and want to hook up to talk about emacs and ruby or something, let me know. I’m ‘lathinet’ on AIM. My cell is 513-295-2844.

Posted in ,  | Tags ,  | 1 comment

Yet another tale of Apache and Mongrel

Posted by Doug Tue, 05 Sep 2006 14:46:00 GMT

It’s clear mongrel is hot. There seems to be a million “tutorials” out there for setting up Apache to proxy to mongrel servers. When I wasn’t ready to set it up, it seemed like every couple blog posts was about how to do it. Once I got ready, I couldn’t find one that fit my situation. So, I thought I’d write up my experiences in the hope that someone doesn’t have to repeat my mistakes.

First, I’m running on Debian sarge. I like to stick with Debian’s package management when I can. Right now my one exception is that if it’s available as a gem, then I use that instead of the .deb. The biggest problem sarge presents to mongrel is that it ships with ruby 1.8.2 and mongrel requires 1.8.4. I followed these instructions on the Bytemark Hosting for building my own .debs for 1.8.4. This let me stay with debian’s package management, but still get a good version of ruby. I also built libdbi-ruby1.8 from source using basically the same steps.

Second, mongrel is pretty easy to install: sudo gem install mongrel. Then from your application’s root, just run mongrel_rails start. Unfortunately, installing from gem like this means you don’t get any fancy /etc/init.d/ scripts to start and stop the mongrel servers at boot time. I did see a nice post on Jens Kraemer’s blog that mentioned a mongrel package in experimental that does manage the start and stop of in a pretty elegant way. I’ll look forward to seeing that come to fruition.

Finally, the kicker: setting up apache to proxy to mongrel. Call me whatever you will, but I’ve still got apache 1.3 running as my primary web server. There’s not a lot of docs out there that say you can proxy from apache 1.3 to mongrel. As it turns out you can. I fought for a long time though getting it to work and eventually gave up. I ended up grabbing a “extra” IP address and running apache 2.0 out of debian sarge on that address. Horror of horrors, once I set all this up I still had the exact same issue trying to proxy 2.0 to mongrel as I did proxying 1.3 to mongrel.

Mongrel was running fine. I could connect a browser directly to the mongrel server and run the app all day long. The problem was definitely apache. I tried running mongrel in debug mode to see detailed logs. I tried using tcpdump to view the traffic between apache and mongrel. To no avail. When I loaded the first page of my app, it redirected me to the login. All my clients would get this far. When they tried to follow the redirect, it failed like this:


HTTP/1.1 400 Bad Request
Date: Tue, 05 Sep 2006 03:29:14 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>400 Bad Request</TITLE>
</HEAD><BODY>
<H1>Bad Request</H1>
Your browser sent a request that this server could not understand.<P>
<HR>
<ADDRESS>Apache/1.3.33 Server at lawnbutlers.lathi.net Port 80</ADDRESS>
</BODY></HTML>

After much weeping and wailing, it turns out the the trailing slash in your apache config is important:


<VirtualHost shaggy.sus4.net>
  ServerName foo.bar.dom
  ServerSignature On
  ProxyRequests Off
  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>

  ProxyPass / http://localhost:4141/
  ProxyPassReverse / http://localhost:4141/
  ProxyPreserveHost On
</VirtualHost>

Without that trailing slash on the ProxyPass and ProxyPassReverse, apache tries to forward the requests to addresses like http://localhost:4141user/login, which clearly won’t work. Of course, I feel silly it took me so long to realize this was my mistake. I’ve seen plenty of other places where trailing slashes are important.

I guess what frustrated me the most was the lack of transparency in debugging the problem. I finally figured it out because apache 2.0 actually listed the bad uri in it’s error message. The error wasn’t the request the browser was sending to apache. It wasn’t the request the mongrel server was getting. In fact, the mongrel server never got the bad request. It was the request apache was generating on behalf of the browser. But that request wasn’t hitting “the wire” to be sniffed by tcpdump because it was bad. The only solution here was to improve the logging within apache itself.

Posted in , , , ,  | Tags , , ,  | 3 comments

Older posts: 1 2 3 4 ... 14

Copyright 2001 - 2005 by Lathi.net and Doug Alcorn

Creative Commons, Some Rights Reserved Ruby on Rails Developer Powered by Debian GNU/Linux Powered by Typo