That Rails Thing


I need to join the fray. Pat Eyler has announced a competition together with APress. The first installment is about how Rails has made me a better programmer. Details to be found here.

So, let’s get at it. Rails has inspired and affected me in numerous ways. You got to realize that I have been programming web applications in Java for way too many years. Before that I’ve done both ASP and PHP. Nothing ever felt natural. I’ve tried many of the LISP frameworks (and Uncommon Web is really cool). I’ve embraced continuation-based frameworks. But none felt so powerful, yet nonintrusive. Rails embodies the best parts of Ruby.

For me, Rails is very interesting for several reasons. First and foremost is the fact that it is an incredibly good framework. It’s really amazing how good it is. And that in itself acts as an inspiration. To know that software can be this good makes me want to strive to perfect my API’s, make my libraries more usable, and finding new and novel ways to improve my DSL’s.

But that’s only part of it. The flip side of this is that Rails is not perfect. In fact, there are myriad ways it can be improved. And that gives me hope, because it also means that no matter how good my code gets, it can always get better. And that means I’ll never be totally bored!

In a very literal sense, Rails has made me a better programmer in another way. Since Ruby on Rails was the first Ruby-application to make it into Karolinska Institutet, it means I can thank Rails for being able to write more Ruby at work. And writing Ruby instead of Java must make you a better programmer, neh?

Of course, Rails is an excellent testing tool for seeing how far we have left with JRuby. It goes without saying that you become a better programmer by implementing a language…

I have several applications and libraries that I keep in mind when writing my code. Those libraries act as a gauge against which I measure my code. Code quality, testing ability, interface, sheer trickyness; in all these areas, Rails is one of the top frameworks I know.



Some notes from the Stockholm Rails meet


Last night (Wednesday) about 35 developers with an unhealthy interest in Rails met up in Stockholm, at Valtech’s offices, to share some experiences and talk shop.

It was very interesting and fun to meet people I can relate to. We ended up talking programming languages for a few hours after the main event ended.

Peter Marklund did a presentation on a CRM system in Rails, and Christian and Albert from Adocca talked about caching, and handling a Rails application that needs to scale into the millions. Nice stuff.

Last, I did an improvised presentation on LPW, a small Rails application that is fed its main data through Web Services instead of ActiveRecord. I believe it went fairly well, even though I had no slides and almost no preparation… =)



Speakings this and next week


Just a quick notice. I will be talking this wednesday at a Rails group in Stockholm. The subject will (for once) not be about JRuby, at least not primarily. Instead I will talk about an application called LPW, which is interesting since it doesn’t use a database as the main data feed, but a bunch of Web Services that are implemented by a third party and deployed with EJB’s in Axis. I had all kinds of challenges, but in the end the result became very good. I will talk a little about what you can expect when trying to interface with Java in this way, and good tricks on how to handle an alternative to ActiveRecord as model.

I’ve written a bit about LPW sometime this summer, if anyone is interested.

Next week is the JavaForum meet up in Stockholm, and I will speak after Rob Harrop. The subject is JRuby and the day is Tuesday. As far as I know, the meet up is full.

The presentation will be pretty standard JRuby fare for Java developers.



Announcing ActiveRecord-Mimer 0.0.1


The initial version of ActiveRecord-Mimer have been released.

The project aims to provide complete ActiveRecord support for the Mimer SQL database engine. This initial release provides the basis for that. Most operations work, including migrations. The only exceptions are rename_column and rename_table which isn’t supported by the underlying database engine.

The project resides at RubyForge: http://rubyforge.org/projects/ar-mimer

and can be installed with RubyGems by
gem install activerecord-mimer

The code is released under an MIT license.



The JRuby Tutorial #3: Playing with Mongrel


This part of the tutorial will be based on some slightly not-released software, but since it is so cool, I bet you will try it anyway. Basically, what I’m going to show you is how to get Mongrel 0.4 working with JRuby, and then how you can serve your JRuby on Rails-application with said version of Mongrel.

What you’ll need
First of all, check out the latest trunk version of JRuby. There are some smoking new fixes in there that is needed for this hack. Next, you will also need to check out the 0.4-branch of Mongrel. This can be done with the following command:

svn co svn://rubyforge.org/var/svn/mongrel/branches/mongrel-0.4

You need to manually copy two parts of mongrel into your JRuby home. If $MONGREL_SRC is the name of the directory where you checked out mongrel, these commands will suffice:

cp -r $MONGREL_SRC/lib/mongrel* $JRUBY_HOME/lib/ruby/site_ruby/1.8
cp $MONGREL_SRC/projects/gem_plugin/lib/gem_plugin.rb $JRUBY_HOME/lib/ruby/site_ruby/1.8
echo '#\!/usr/bin/env jruby' > $JRUBY_HOME/bin/mongrel_rails
cat $MONGREL_SRC/bin/mongrel_rails >> $JRUBY_HOME/bin/mongrel_rails
chmod +x $JRUBY_HOME/bin/mongrel_rails

You will need to download the JRuby-specific http11-extension library. This can be downloaded here, and should also be put in the $JRUBY_HOME/lib/ruby/site_ruby/1.8-directory.

You’re now set to go.

Simple web hosting
I will now show how to set up at small web server, that can serve both files and servlets. There really isn’t much to it. First of all, we need to include some libraries:

require 'mongrel'
require 'zlib'
require 'java'
include_class 'java.lang.System'

Next step is to create a simple HttpHandler (which is like a Servlet, for you Java-buffs):

class SimpleHandler < Mongrel::HttpHandler
def process(request, response)
response.start do |head,out|
head["Content-Type"] = "text/html"
results = <<-"EDN";
<html>
<body>
Your request:
<br/>
<pre>#{request.params.inspect}</pre>
<a href=\"/files\">View the files.</a><br/>
At:
#{System.currentTimeMillis}
</body>
</html>
EDN

if request.params["HTTP_ACCEPT_ENCODING"] == "gzip,deflate"
head["Content-Encoding"] = "deflate"
# send it back deflated
out << Zlib::Deflate.deflate(results)
else
# no gzip supported, send it back normal
out << results
end
end
end
end

Now, this handler basically just generates a bunch of HTML and sends it back. The HTML contains the request parameters. Just to show how easy it is to combine Java-output with Ruby-output, I have added a call to System.currentTimeMillis. This could of course by anything. The last part is to actually make this handler active also. To finalize, we also start the server:

@simple = SimpleHandler.new
@http_server = Mongrel::HttpServer.new('0.0.0.0',3333)
@http_server.register("/", @simple)
if ARGV[0]
@files = Mongrel::DirHandler.new(ARGV[0])
@http_server.register("/files", @files)
end

puts "running at 0.0.0.0:3333"

@http_server.run

If you start this script with:

jruby testMongrel.rb htdocs

you can visit localhost:3333 and expect to see some nice output.

Making it work with Rails
A prerequisite for this part is that you have a functional JRuby on Rails-application using ActiveRecord-JDBC. If that is the case, you just need to go your application directory and execute this command:

$JRUBY_HOME/bin/mongrel_rails --prefix "" start

and everything should just work.

So, that’s it. JRuby on Rails, with Mongrel. Enjoy.



Two things in Rails


This will be a short in-between post. Don’t expect to be annoyed, enlightened or even trivially entertained. I’m just going to describe two small things I do in all my Rails-projects, and I haven’t found a way to do them as plugins. This is very annoying, of course, so I hope someone from the Rails team will eventually see this and tell me how to do it DRY.

1. Add a production_test environment
I feel constrained by the three environments that get delivered by Rails out of the box. And I find that for every project where the customer isn’t myself and the codebase is bigger than about 50 lines of (hand-written) code, I tend to add a new environment to Rails; ‘production_test’. The problem this environment solves is the situation where I want my customers to test out an application, but I don’t want them to do it against a real production environment. For example, I did an application called LPW a few months back, that works against a 3rd party web service. This web service has one production environment and one test environment. I want the production_test to be as fast, responsive and generally as much as the production environment as possible, but not go against the production web service. I solve this by adding a production_test env which is exactly like the production environment, except I can just change the address to the web service endpoint to the test one.

I usually do this, so I can give my customers a nice application that they can play with, but without worrying about them damaging production data.

2. Add plugin environment configuration
This is actually a major pain. I have developed a few plugins, and generally I want them to have configurations based on which environment we are in. For example, the CAS authentication plugin shouldn’t really redirect to the CAS server when in development environment. But, I can’t set this in any good way, since the plugins will be loaded after the environment-specific files have been loaded. So, what I do is simply to add a new directory, called config/plugin and in environment.rb I have this:

 plugin_environment = File.join(RAILS_ROOT,'config', 'plugin', "#{ENV['RAILS_ENV']}.rb")
load plugin_environment if File.exist?(plugin_environment)

This solution sucks, but it works.