avatarharuki zaemon

Daily Musings

By

Be warned, this is somewhat of a stream-of-consciousness even if a little edited.

I was sitting at work today pondering, among other things, some particularly awful code that we happened upon – so what’s new? The code in question relied upon multiple columns in a table to hold configuration information when really what was needed were multiple rows – something like a properties file but in a database. I then started to think that I pretty much always start out wanting my data to be “properly” normalised without regard to performance considerations. As Knuth is oft-quoted as saying, “premature optimisation is the root of all evil.”

One thing I really like is when a development environment allows me to easily layer on performance enhancing behaviour such as caching, without unduly interfering in the core design of the system. In a Rails for example, I can build a completely dynamic application and strategically add caching where necessary for content that is, for the most part, static. If the data on which that content relies changes, expire the cache and it’ll be re-generated.

At the same time, I was pondering why it is that I like Ruby so much and why I believe it really makes development environments such as Rails possible; in a way that Java just doesn’t. Although a topic for another blog entry, one of the reasons I considered was it’s dynamic (ie non-compiled) nature. That I can change a piece of code and immediately run it without a compilation step is, IMHO, a big factor. (I’ll grant you that Eclipse goes a long way towards achieving this for Java with its continuous compilation but I feel there is more to it than just that.)

It then occurred to me that compilation, or, more specifically, the translation of source-code into some executable form and stored in some more persistent manner (such as files on a hard disk) is really a form of caching.

To see what I mean, imagine you started with a fully, 100% interpreted language where each statement is re-parsed each time it is executed. Ie. no caching. To this you then decide to convert the source-code into an intermediate, in-memory, form to remove the need to re-parse the source-code each time. This is a first-order cache. Finally, you decide to write this intermediate form to a more persistent medium so as to remove entirely the need for conversion from raw source-code to an executable form. This is a second-order caching. You could of course further translate the intermediate form into native machine code or any number of intermediate formats. And, of course, once in memory, the intermediate format could be dynamically translated into machine code – such as a Just-In-Time compiler or Hot-Spot compiler does.

The point I’m trying to make however is not how efficient one can make the execution process but simply that it is entirely possible to execute the raw source-code with a very simple parser and interpreter. The fact that we choose to further translate that source-code to forms specifically designed to improve execution efficiency is an optimisation and, in many ways, not so different to storing the output from a Rails action on the server, or a web browser caching an image or an HTML page.

Where the analogy breaks down of course, is that compilers often provide other benefits such as detecting poor or incorrect use of the langauge. That said, some of these benefits are lost – or for that matter not even useful – when using languages such as Ruby and yet other benefits might be found in static analysis tools.

So, what does this all have to do with anything?

That’s a very good question to which the answer may well be “not very much at all” however, I did find it interesting to ponder, as one does ;-)

One thing that I have noticed though, speaking of source-code, is there exists a distinct difference in the way the Ruby versus Java communities treat the sharing of code.

In the Java community, sharing of code is largely done by means of pre-compiled libraries with accompanying documentation. Sure, we have open source projects which make the source-code freely available for (ab)use. But, and I admit to having been guilty of this myself, the general feeling is don’t modify the source unless you really need to; treat the binary distribution as a black box. And perhaps for good reason?

In the Ruby (and apparently Smalltalk) community, the philosophy is more one of source-code sharing. Need a Rails plugin? download the source-code into your source-tree; Looking for some missing Ruby functionality? Native extensions aside, what you’ll get is a bunch of source-code. In most cases the source-code also comes annotated with RDoc – the Ruby equivalent of Javadoc– but even still, being confident to look into the source-code is, IMHO, a bonus.

Of course, there are those who would argue that sharing of raw source-code isn’t always a commercially viable option and perhaps they’re right.

In any event, I’m not sure I have enough experience in either yet to have formed an opinion as to which (or even if) one approach is better than the other but I do wonder if the fact that one is primarily treated as a compiled language whereas the other is essentially treated as interpreted leads to at least some of the differences in culture that I see or if I have cause and effect around the wrong way.

A Plea to JetBrains

By

I’m back doing some Java work at the moment and although coding in Java feels somewhat like trying to speak with a mouthful of peanuts – compared with Ruby – I’m rather enjoying it for some perverse reason. That said, my long-time trusty steed in such endevours is really beginning to annoy me. IntelliJ, once the lean, mean, IDE has porked out considerably over the last few releases. It seems that in competing with Eclipse, it is becoming Eclipse: fat, bloated and slow.

IntelliJ has become a bit like Micro$oft Word: I only ever use 5% of the features – and that’s just the features of which I’m actually aware; I’m beginning to need the 2GB of RAM in my laptop just for IntelliJ; oh, and SVN+SSH integration just plain sucks. I’ll be sticking with the command-line version thank you very much.

It’s all very well and good to have all these nifty tools, etc. in the IDE but seriously, I never use them. Nor, for that matter, do I want to get into the habit of doing so for one simple reason: I have command-line build tools so that I may run the build on any machine, at any time of the day, even gasp when there is no IDE involved nor a programmer to be found.

So here’s a plea to JetBrains: I paid good money for your software and I’ll be more than happy to continue paying good money if you’ll please oh please let me turn off all those features that make me feel more like I’m using WSAD.

What’s next, Perspectives? Gadzeeks!

A Nation of Zombies

By

I’m usually reticent about making politically motivated blog entries but today I was having a to-and-fro via email with a friend of mine when she made a statement that, especially in light of the hoopla surrounding a certain TV show here in Australia, I felt was too good not to quote:

It’s a pity that the people who watch Big Brother don’t equally scrutinise the behaviour exhibited on that other reality TV show, ‘Parliament Question Time’.

Here, here.

No More Delicious Links

By

When I moved to FeedBurner I hardly ever used delicious and I thought it might be interesting to have any new links included as part of my feed. These days however, I find myself adding links to delicious on a regular basis and my feed has been somewhat flooded as a consequence. So, by request, I’ve removed the links from the feed. You can always subscribe to them using delicious anyway if you really cared (not that you probably did).

No Software Keys Required

By

Ever since I made Simian available, I’ve had a strong belief that the software should be available for download in a non-crippled form. That is, whether you pay for it or not, makes no difference to the functionality; you are however left with a clean conscience :)

Unfortunately, this is something that many customers find quite difficult to come to terms with. Many of them, after parting with a relatively small sum, insist they be sent a license file, software keys, or something else tangible for their money. I’m at the point now where I’m considering simply sending out a file containing 128-bytes of randomly generated gibberish that they can place in the software directory just to give them that warm, fuzzy feeling.

Did I miss some unwritten rule that says a polite email thanking them for their purchase isn’t enough?

svn:externals

By

This relatively unknown feature of subversion allows you to include one subversion repository URL inside another. By that I don’t mean export and add, rather svn:externals allows you to create a virtual directory that links to an external repository.

I’m sure there are plenty of other uses but I mostly use svn:externals for adding plugins to my rails projects. For example, if you wanted to link to the Foreign Key Migrations plugin, from inside your rails project directory you would type:

simon$ svn propedit svn:externals vendor/plugins/

Then add the following lines:

foreign_key_migrations svn://rubyforge.org//var/svn/redhillonrails/trunk/vendor/plugins/foreign_key_migrationsschema_defining svn://rubyforge.org//var/svn/redhillonrails/trunk/vendor/plugins/schema_defining

And voila! Now when you update your project you’ll see something like:

simon$ svn upFetching external item into 'vendor/plugins/foreign_key_migrations'External at revision 25.Fetching external item into 'vendor/plugins/schema_defining'External at revision 25.At revision 2533.simon$

Notice how subversion updates the virtual directories as well.

Be aware though that this does mean you’ll always get the latest code when you update. This is exactly what I want but may not suitable on all projects. Sometimes a simple svn export is more appropriate.

We’re currently toying with the possibility of using svn:externals to share common code between some projects that are presently all in one big code-soup project but will be split up over the next couple of months. I’ll let you know what we decide to do in the end.

Perhaps Pluralize Means Something Other Than I Thought

By

Besides the unfortunate use of a z where there really ought to be an s (yes, yes, I’m Australian), what does this word really mean?

pluralize v. tr.* To make plural.

  • Grammar. To express in the plural.

OK, that’s pretty much what I thought it meant. So then riddle me this Batman:

simon$ ./script/consoleLoading development environment.>> "country".pluralize=> "countries">>

Good good. Just as expected. So, now let’s try something else:

>> "countries".pluralize=> **"country"**>>

Huh??? Since when did country become the plural of countries?

They say we go through three career changes but really...

By

Ok so I’m an Aikido guy but I’m sure this will amuse most non-aikido people as well. Apparently it’s legit! So now I can’t help but make up funny movie titles:

Pushed to the brink by the death of his movie career, a down and out martial artist gives it one last go…Steven Seagal in: Out of Tune…coming to a cinema near you.

Schema Defining Plugin

By

Just a quick update on my plugins. Two of them – Foreign Key Migrations and Row Version Migrations – needed to know if they were being run as part of ActiveRecord::Schema.define() so I extracted the common code into yet another plugin: Schema Defining. This new plugin provides a class method – ActiveRecord::Schema.defining? – that returns true if ActiveRecord::Schema.define() is currently running; false otherwise. Probably not a hugely useful plugin in the main but certainly a must have if, like me, you have a number of migration plugins that need to alter their behaviour accordingly.

Row Version Migrations

By

The more I use Rails, the more plugins I seem to create. Each time I start a new project, almost the first thing I find I want to do is to copy a chunk of code from an existing project. The moment that happens, I think: Plugin!

So here it is. A plugin that automatically generates the following row version columns for every table:

:created_at,   :datetime,  :null => false

Not so difficult. In fact it seems almost trivial (as usual) but it means all my tables now get date/time stamps and optimistic locking for free.

Enjoy. As always, feedback, suggestions, patches, criticism, all welcome.

Alias a Static Method in Ruby

By

As much as I love Ruby on Rails, one of the things that dissapoints me is the rather large number of static methods. Maybe it’s my Java background but class methods just irk me: They’re difficult to override, mock, stub-out, and they’re inherintly thread-unfriendly. But that aside, the fact remains that they exist and, now and again, I need to mess with them. Case in point: My Foreign Key Migrations plugin.

The plugin was working fantastically – thanks to the efforts of Ted Davis for giving it a work out – until it came time to running functional tests. Unfortunately, but unsurprisingly, the schema dumper used to copy the database structure from development to test creates tables in alphabetical order. Now I can’t actually think of a much better alternative but the problem is that this means the foreign key clauses were being generated against tables that possibly didn’t exist at the time of execution. (For example, Order sorts before Product however the orders table has a foreign key to the products table.)

So anyway, the longer-term solution is to batch up the foreign-key declarations until the end of the script and then execute them but in the meantime, I just wanted to disable their generation altogether. In either case, I needed to interfere with the execution of ActiveRecord::Schema.define a static (boo, hiss) method. Now, for the fun bit.

In Ruby, the way to safely mix-in methods (rather than use subclassing) is to use some method chaining. For this we use alias_method. So, for example, if we wanted to override to_s to always place quotes around the value (nopt very useful but it will suffice for now) we could write a module like this:

module QuoteToSdef self.included(base)base.class_eval do**alias_method :to_s_without_quotes, :to_s** unless method_defined?(:to_s_without_quotes)**alias_method :to_s, :to_s_with_quotes**endenddef to_s_with_quotes"'#{to_s_without_quotes}'"endend

This essentially says that when the module is included (ie mixed-in) to a class then: add a method named to_s_with_quotes; create an alias of the existing to_s named to_s_without_quotes; make an alias of the new to_s_with_quotes named to_s; and finally, whenever to_s. is executed, call the old to_s method (now named to_s_without_quotes) and surround the results with, you guess it, quotes.

To use this you would either manually include the module in a class or, more along the lines of aspects, force the inclusion with some code like this:

MyClass.send(:include, QuoteToS)

(As a side note, the use of unless method_defined?(:to_s_without_quotes) is to work-around a bug in Ruby 1.8.4 that causes an infinite recursion when using alias_method. I never detected it under Mac OS X but apparently it affects windows machines with monotonous regularity. D’oh!)

So that’s all very well and good but what happens when you need to do the same thing with static methods? The answer is, use class << self and extend. In my case, overriding the behaviour of ActiveRecord::Schema.define looks something like this:

module ForeignKeyMigrations::Schemadef self.included(base)**base.extend(ClassMethods)**base.class_eval do**class << self**alias_method :define_without_fk, :define unless method_defined?(:define_without_fk)alias_method :define, :define_with_fk**end**endend**module ClassMethods**def define_with_fk(info={}, &block)...define_without_fk(info, &block)endend**end**

Here, the use of base.extend causes all the methods defined within the module ClassMethods – an aribitrary name used by convention in most if not all the rails code I’ve ever seen – to be added as static methods on the class. Then, surrounding the alias_method calls within a class << self causes them to be executed in a static context.

Again, to have this code mixed-in to the existing ActiveRecord::Schema class looks like this:

ActiveRecord::Schema.send(:include, ForeignKeyMigrations::Schema)

Phew!

P.S. all the plugins are now available via SVN.

UPDATE: See the comments on how to simplify the code thanks to Ryan Tomayko.

Publishing My Rails Plugins

By

I’ve created a page where I’ve started to publish my rails plugins. I don’t yet have a publicly accessible SVN server but I’m in the process of setting one up so, until I get that completed, I’ve packaged the plugins as downloadable .tar.gz files that you can extract into your vendor/plugins directory. So far I’ve published the foreign-key migrations and cascading stylesheets plugins with more to come. But as today is Norway’s national day (apparently celebrating the signing of the constitution on the 17th May, 1814) and I’m in Olso, I’m off to do some drinking..ahem I mean..celebrating.

Auto-Generate Foreign-Key Constraints in Rails

By

I literally just lobbed into my hotel room in Oslo after 30+ hours in transit. (I left home @ 12:30pm on Monday 15th and arrived here @ 21:30 on Tuesday 16th Melbourne time.) It’s my first time in Scandinavia and so far I’m loving it. The people are friendly (and ahem rather attractive I must say) and I’m hanging out to try some scandinavian beer!

So anyways, after resisting the temptation to turn on my laptop, I finally caved and whipped up a little bit of code to auto-generate foreign-key relationships for migration scripts:

module ActiveRecord
  module ConnectionAdapters
    class ColumnDefinition
      alias nofk_to_sql :to_sql

      def to_sql
        name.to_s =~ /(.*)_id$/ ? "#{nofk_to_sql} REFERENCES #{Migrator.proper_table_name($1)} (id)" : nofk_to_sql
      end
      alias to_s :to_sql
    end
  end
end

The code assumes that if you have a column named customer_id in say an order_s_ table, then you want a foreign key to the id column in the customer_s_ table. That doesn’t handle situations where you have multiple foreign keys to the same table but…meh…I don’t have models that sophisticated yet so bite me :)

Just looking back on it now, it was so trivial to implement that there is more syntactic noise than actual code. Hmmmm.

UPDATE: The plugin is now available in downloadable form and supports a :references option for multiple columns or columns that aren’t named for the table they reference.

Using a Single Development Database For all Rails Applications

By

I used to have a separate database and/or user for each application I was developing. This worked for a while but once I had three or so projects underway, I grew tired of remembering which database and which login to use when running psql, etc. In addition, if anyone else wanted to do development, they too needed to either configure another rails environment (eg. james_development) or they had to create another database/user just as I had.

Then it occurred to me that psql (at least under Mac OSX) defaults to connecting to a database named for the currently logged in user. So, I reasoned, if all the developers had a default database, then if I could configure rails to connect to that I might be rid of my myriad databases. The problem was: how?

At first I tried not specifying a database in config/database.yml at all. D’oh! No luck. Then I wondered if I could add an ERB-ish macro for the current user (I may even have read that it was possible but I can’t for the life of me recall where):

development:adapter:  postgresqldatabase: **<%= ENV["USER"] %>**username: **<%= ENV["USER"] %>**

I’m not sure at what level this is being handled (rails, yaml, ruby, somewhere in between) but it worked! Now when the application loads in development, the name of the currently logged in user is substituted in for the name of the database.

The only other thing is to always remember to specify a table-name prefix in config/environments/development.rb and all the applications will happily co-exist in the same, default, database:

  config.active_record.table_name_prefix = "cjp_"

I’ve been playing with having all my applications in the one development database for a while now and it seems to be working out ok. On the down-side, it does mean I need to remember the table-name prefix when using psql, in some ways moving the problem rather than removing it, however it doesn’t seem to get in the way especially because psql has table completion for table-names, column-names, indexes, you name it. (That’s right: select * from cjp_[tab] where [tab] = '...';). The other downside of course is if I ever want to blow away the entire database I can’t but then again, that’s what rake migrate VERSION=0 is for.

I’m not sure if I’ll continue in the long-term with this but it sure makes adding a new developer to the team dead-simple and makes my local machine configuration a lot simpler in the meantime. Besides, I needed an excuse to try using table-name prefixes so I could test my migration extensions. Guess what? They didn’t handle it! They do now :)

Transactional DDL

By

Have you ever been half way through a rails migration script only to have it bomb out with some error or another? You then correct the error and try to re-run it but because some of the statements have already been executed they fail when executed a second time.

Some databases (PostgreSQL for example) allow you to wrap DDL (Data Definition Language, create table, etc.) as well as DML (Data Manipluation Language, insert, etc.) in a transaction! This means that if any part of the script fails, the whole lot is rolled back. Imagine this: you drop a table, script rolls back and the table magically re-appears as if nothing had happened.

In rails migration scripts it’s a simple matter of wrapping the entire up and/or down method with a _Model_.transaction do ... end. (Yet another time I really think the idea of making transactions a part of the model is particularly ridiculous. Transactions are cross-cutting concerns just like logging. Just ask the Aspect weenies, they’ll tell ya.)

Here’s a simple example:

def self.up
  SystemProperty.transaction do
    create_table :system_property do |t|
      t.column :name,         :text,      :null => false
      t.column :value,        :text,      :null => false
      t.column :created_at,   :datetime,  :null => false
      t.column :updated_at,   :datetime,  :null => false
      t.column :lock_version, :integer,   :null => false, :default => 0
    end
    add_index :system_property, [:name], :unique => true
  end
end

Now, I realise that create_table also supports the :force => true option so this is possibly not the best example but at least you can see how to go about making your migration scripts fully transactional, DDL and all.

Hej Sweden (and Norway)

By

I’ll be in Oslo from the 16th until the 19th of May then in Arvika from the 19th until the 22nd and finally Stokholm from the 1st of June until the 7th of June, visiting parts unknown in between so if anyone wants to meet up for a beer and Surstromming (NOT!), that’d be cool. I’ll be doing some work-related stuff as well as attending a few Aikido seminars. Any recommendations? Places to visit? Things to see? Hotels, Motels, Hostels to stay at (or avoid)?

Bulletproof Web Design

By

You know that feeling when you grok a programming language so that you spend far less time thinking about the how and thus are free to concentrate more on the what? That’s how I feel about Java and it’s how I’m beginning to feel about Ruby and Rails. The same can’t (or I should say couldn’t) however be said for (X)HTML+CSS. Until now.

Having scoured the net, read every web site I could find and even sat in bookstores for hours reading Eric Meyer, I still didn’t feel comfortable doing web page layout and design. I just didn’t get it. I spent so much time trying to work out how I would create a web page that I lost all my creative drive. I new there just had to be a simpler way. Surely (X)HTML+CSS gives me syntactic markup + layout?!

Finally, in a last ditch effort to put myself – and my friends on IM who I wouldn’t stop bitching to – out of misery, I spent a few hours in Borders (you know, the library with coffee) and stumbled upon Bulletproof Web Design by Dan Cederholm.

It’s a pretty easy read and the examples are very easy to follow. The layout of the book makes a big difference too. I love books that I can just open at any page and get a “nugget” then read on if I feel inclined to do so or even skip back a bit to learn a bit more. This is in stark contrast to the excellent but – for me at least – excruciatingly painful Eric Meyer books which are too densely packed and concentrate too much on the what rather than the how.

I’m still no expert (I’ve really just started) but if you too are in need of some very simple yet practical help in getting you started thinking with the right mindset, I can highly recommend it. If however you’re after an HTML+CSS reference manual or an O’Reilly hacks style of book for that matter, then you might like to try something else.

More Managing Multiple Rails Environments

By

Yesterday I discussed how we made sure our application was talking to the correct database. Today I’m going to show you how we provide some visual feedback to the user indicating in which environment they’re operating.

As mentioned yesterday, we have four different environments, two of which – UAT and production – are available to the end users and as such it’s imperitive that we provide some visible means for discrimination (lest they mistake one for the other and accidentally add test data into production). Besides obvious gating procedures such as different access rights, etc. one of the ways we can help them out is by providing some obvious visual feedback to indicate the current environment. In this scenario, we decided to change the background colour from gold in production to red in UAT.

One approach might have been to hard-code some style information into the head element of the main application.rhtml template. Something along the lines of:

<% if RAILS_ENV == "uat" -%&gt<style type="text/css">body {background-color: red;}</style><% end -%&gt

The problem with this approach is that, well quite frankly, it smells. For a start, we’ve hard-`d the environment and placed style information directly into each web page – something I’m always reluctant to do if I can avoid it. So what other options do we have?

I’m glad you asked. It turns out that we already had a mechanism in place for including various stylesheets depending on which page is being rendered. For a start, we always include application.css on every page. It contains all the global, system-wide styling information. In addition, we also include a stylesheet for each page – if it exists – based on the path to the current action. So for example, if the current action is list in the CustomerController then we check to see if the stylesheet customer/list.css exists and if so, include it in the rendered output. This allows us to easily add specific styling for individual pages if necessary.

The code for the macro that handles this behaviour looks something like:

def stylesheet_link_tag(*sources)if sources.include? :defaultssources = sources.dupsources.delete :defaultssources << 'application' if File.exists?("#{RAILS_ROOT}/public/stylesheets/application.css")page = "#{@controller.controller_name}/#{@controller.action_name}"sources << page if File.exists?("#{RAILS_ROOT}/public/stylesheets/#{page}.css")endsuper *sourcesend

So if you call the stylesheet_link_tag macro with :defaults as one of the arguments, magic happens.

With this in mind, we decided to enhance the default stylesheets list to include #{RAILS_ENV}.css if it exists (with a little DRY re-factoring in the process):

def stylesheet_link_tag(*sources)if sources.include? :defaultssources = sources.dupsources.delete :defaults['application', **RAILS_ENV**, "#{@controller.controller_name}/#{@controller.action_name}"].each do |source|sources << source if File.exists?("#{RAILS_ROOT}/public/stylesheets/#{source}.css")endendsuper *sourcesend

Now we can easily create a uat.css that looks something like:

body {background: #EB5E66;}

And voila! When users log in to production they see the default (gold) background and in UAT they’re immediately hit with a red – technically it’s ‘cherry’ – one. No mistaking which environment they’re in now.

Again, you don’t have to use a background colour nor even use stylesheets for that matter. The main point is that getting configuration management (of which we consider this to be a part) takes some thought but isn’t that hard to get right, especially in Rails.

Managing Multiple Rails Environments

By

I’ve written briefly on build watermarking and environmentally friendly builds before: Some useful techniques to aid support staff in identifying which particular build of your application is causing your end-users – or testers as is often the case – grief.

In the first of these two articles, I mentioned a project we did many years ago where we stored the build number in the database. When the application connected, it checked to that it was running against the correct database version. This was prompted by one of our biggest clients at the time who had several hundred users all running a client-server application (yes it was a loooong time ago) and we needed to ensure they couldn’t accidentally run the wrong version and potentially corrupt the database.

A similar problem has now cropped up with a rails application we’re developing. This time, rather than a specific build, we’re more interested in ensuring that the application is running against the correct database instance. In this scenario, we have four databases: development; test; uat; and production. Not so much a problem for the first two, but it’d be pretty catastrophic if somehow the UAT application were started against the production database!

Our solution is pretty simple and inline with the previous discussion: put something into the database to identifiy the appropriate environment then check for it in the rails application. The implementation (naturally being rails and all) was also quite simple. We already had a generalised SystemProperty class – essentially just a set of key-value pairs supporting hash-like indexing – o we merely created a new instance, :environment, which is then checked via before_filter in the ApplicationController like so:

class ApplicationController < ActionController::Basebefore_filter :check_rails_env...def check_rails_envraise "Incorrect database: '#{SystemProperty[:environment]}' expected: '#{RAILS_ENV}'" \unless SystemProperty[:environment].value == RAILS_ENVendend

Once the code is in place, all you need do is insert a record into the system_properties table with a key of 'environment' and a value of say 'production' (for, you guessed it the production database) and you’re good to go. If the application ever runs against the wrong database, you’ll be greeted with something along the lines of:

Incorrect database: 'production' expected: 'uat'

A slightly riskier alternative to creating the environment record manually is to perform the task in a database migration script:

class CreateEnvironmentSystemProperty < ActiveRecord::Migrationdef self.upSystemProperty.create! :name => "environment", :value => RAILS_ENVenddef self.downSystemProperty[:environment].destroyendend

I can’t say I particularly recommend this approach though unless you are REALLY, REALLY certain of your environment settings – precisely what you probably aren’t if you’re considering the whole idea in the first place – but, nevertheless, maybe, like me, you just want to ensure that no one can screw up in the future, say while you’re on holidays and you’ve left it up to the new guy ;-)

The one place where this approach falls down is with caching. Because we’ve used a before filter, any actions that are cached will be served up directly by the web server, without going through the rails controller. Practically though, I doubt this will be much of an issue, especially in our particular case where what we’re really worried about is back-office staff either entering data into the UAT database when they thought it was production – a bit of a waste of time but not that bad – or worse, testers entering data into a live system.

Ofcourse this isn’t the only problem faced by developers tasked with managing multiple rails environments and I hope to address some more in future posts.

The Days I Turned Pluralisations: Off

By

Oh what a day it was.

You see, the first real Rails project we did, I thought, “well, I’ll give it a try. This guy seems to know what he’s talkign about and even though pluralisation goes against everything I’ve ever learned or studied with repsect to database design, why not?”

One of the major factors in making rails so productive (for me at least) is that it reduces the cognitive dissonance – between my ideas (creativity) and the implementation (ruby/rails). I find when I’m coding in rails that it’s enabling me to quite literally code what I’m thinking as I’m creating, in way that Java never has. (That’s not necessarily the fault of Java per-se, rather my feeble brain.) The pluralisation stuff seems to fly directly in the face of this.

Well suffice to say that on my second real project, I decided to turn it off, and my brain thanked me for it. I simply added the following to config/environment.rb:

Rails::Initializer.run do |config|
  ...
  config.active_record.pluralize_table_names = false
end

No longer did I need to keep remembering that even though the class is called Entity the table is called Entities. No more pissing around with pluralisation rules because, what-do-you-know, the default ones can’t handle the fact that the plural of UnitOfMeasure is unit**S**_of_measure. No more switching contexts everytime I go from SQL to Ruby code. (Yes, I manually dig around in the database using SQL to make sure I haven’t screwed something up. And yes, I also use the rails console.)

And you know what? In neither project has the customer once asked me to show them the database schema – one of the arguments supposedly for using plural table names. No, in fact if I ever wanted to show the customer anything (other than the application itself), I usually scribbled labelled boxes on a whiteboard and even then, I’ve not once had anyone give me a puzzled look or ask “why is that singular?” Strange perhaps but true!

So whilst I admire the audacity and coding athleticisim of DHH for creating the pluralisation code, I’m far more impressed with the work he and the team have done on Rails 1.1. Everything seems so much “better”: ActiveRecord for one; and especially RJS templates as another example. At least they had the foresight (even pre 1.0) to allow pluralisation to be turned off!

Halleloujah!