RailsConf Europe

Finally, I’ve gotten around to booking up everything for RailsConf Europe — flights, hotel, the conference itself. I’m signed up for the all-day charity tutorial because, well, it’s just a fundamentally good idea and well worth supporting/encouraging. Though I hope Dave doesn’t go quite as overboard about charitable donations as he did at RailsConf — I’m paying a lot of money to go and talk to people about Rails, not to be lectured at about the money I give to charity! I already give as much as I feel I can afford, thank you very much!

Anyway.

I’ve been plotting my plans for the time I’m in Berlin on Google Maps, messing around with creating my own map:


View Larger Map

I’ll be arriving at the hotel around 14:00 local time, I reckon, and I’m signed up for Bratwurst on Rails. I’m open to making other plans if anybody wants to meet up on the Sunday afternoon?

Convention for RESTful search in Rails?

Back in RailsConf Europe last year, at David’s Keynote, it was said that:

There are unresolved decisions with respect to the restful controllers. In particular, what should the convention be for searching? A separate action? Or parameters passed to the index action?

I don’t suppose a convention has been adopted for this yet? I’m just about to implement search in an application I’m working on and I’d rather go with the 2.0 convention now, rather than fight against it with my wrong decision later. :-)

Update Judging by the implementation of ActiveResource#find it’s parameters passed to index, isn’t it?

Update 2 OK, so what’s the elegant, reusable implementation for FooController#index, turning params into find(:all, :conditions => ...)?

Update 3 I’ve started codifying what I’m doing into a plugin: resource_search. It’s still in its infancy.

Harnessing Capistrano

These are my notes from Jamis Buck’s tutorial on Harnessing Capistrano, all in bullet form.

  • Focus here is on Capistrano 2.

  • Capistrano came from a need. Basecamp was running on one machine and scaling to a second machine made deployment painful.

  • Adhoc monitoring — for checking uptime, disk space, grep logs, status of db slaves — on every server on the cluster.

  • Server maintenance: package management, synchronising configuration files.

  • 2.0 preview: gem install -s http://gems.rubyonrails.com/ capistrano but you must have the prerequisites installed first (net-ssh, net-sftp & highline).

  • Requires a POSIX (*nix) target, ssh access & ssh keys (or identical passwords on all your servers).

  • Capistrano config is now called ‘Capfile’, is a ruby DSL similar to Rake’s DSL, but it’s not the same.

  • set :gateway, 'internet.accessible.machine' will allow you to talk to servers behind a gateway, so the actual app servers aren’t necessarily directly accessible.

  • cap -T (which used to be cap show_tasks) doesn’t show tasks which don’t have a description. So we can hide ‘internal’ tasks which are only called by other tasks.

  • Use cap invoke to run arbitrary commands on remote systems. Doesn’t even need a Capfile if you specify everything on the command line. For example cap HOSTS="app1,app2" COMMAND="tail /var/log/syslog" SUDO=1 invoke.

  • For running multiple cap invoke commands sequentially, use cap shell instead because it will cache the connection.

  • Capistrano 2 introduces namespaces. Woo! Syntax is the same as Rake. Introduces default tasks for a namespace called ‘default’. Eg, the deploy namespace has deploy:default which can be called by doing cap deploy.

  • If set is passed a block, that block is lazily evaluated the first time it is asked for by calling the block. The result is then cached for future uses.

  • cap -s foo=bar is equivalent to having set :foo, "bar" after all your recipes are loaded. cap -S foo=bar does so before recipes are loaded.

  • We have transactions. If a task fails, then the on_rollback handler is called for each of the executed tasks in reverse order. If the rollback handler fails, the whole world ends. Patches accepted!

  • Capistrano overrides ‘load’ and provides similar semantics, but it searches the directories in the load_paths variable. cap -f will load a specified file, but then won’t autoload the Capfile.

  • By default, capistrano is very verbose (-vvv). You can shut it up with -q.

  • Capistrano now has a “core team” with Mike Bailey & Ezra Z.

Deployment recipes

  • Assumptions: using source code control, you’re deploying a rails application, your production environment is all ready to go (dbs, web server, etc) and you’re using standalone fastcgi listeners.

  • capify . creates a minimal Capfile and a basic config/deploy.rb. The Capfile only loads the deployment recipes and the config/deploy.rb.

  • The deployment recipes in cap 2 are now opt-in so that there’s less noise for folks using it in non-deployment scenarios.

  • Capistrano 2 can check for dependencies before deploying — do the appropriate directories exist, is subversion installed? — done with cap deploy:check. Some deps are local, some are remote. We can customise these. Wow, this is neat: depend :remote, :gem, 'tzinfo', '>=0.3.3'

  • For fcgi listeners, still need script/spin to tell capistrano how to start up your app from cold. Can just call script/process/spawner with the appropriate args.

  • 37Signals have started using process supervision (didn’t specify whether it was init/svscan/runit) to keep an eye on their fcgi listeners. Recommends you get your app working before you start messing with it, ‘cos it requires a bit more upfront configuration.

  • Cap 2 introduces deployment strategies which encapsulates the mechanism by which the source code is acquired. Default is ‘checkout’ which will check out a copy from your scm repository. ‘remote cache’ sounds pretty useful to me, which uses the scm repository but caches what’s checked out, so the checkout becomes svn up which should be a bit faster. Controlled by set :deploy_via, :whatever.

  • Volunteers sought to write a CVS scm backend instead of just promising to. Or maybe nobody really uses CVS any longer. :)

Advanced Techniques

  • In cap 1.4 we had single hook tasks before and after each task, eg after_symlink. Trouble was that third party libraries stomped over each other’s after_symlink. Now we have before :task, :do_stuff and after :task, :do_stuff. Better still, these are just wrappers around the generic callback mechanism on. I guess before is on :before, :do_stuff, :o nly => [ :task ] or something like that?

  • Nick the configuration for staging environments from the slides! Yeah, that looks pretty neat.

Upgrading to Cap 2.0

  • With cap 1 & 2 installed, to use cap 1, do cap _1.4.1_.

  • 3rd party extensions and libraries need to be rewritten. For example, mongrel_cluster ain’t gonna work yet.

  • Actor has disappeared and has been subsumed into the Configuration class.

  • If you’ve overriden or extended tasks, you’ll need to figure them in with namespaces. If you used before_task and after_task you should be mostly OK, though.

  • Compat mode to aid the transition. Do cap -Ff compat or load 'compat' to load it. Mostly it’s there to help you learn what the new namespaced task names are.

  • cap -Ff upgrade gives you the upgrade:revisions task which will create #{release_path}/REVISION retrospectively for existing deployments.

  • The render helper has disappeared.

RailsConf 2007: Is Javascript over-rated?

The first tutorial of the weekend I signed up for was “Is Javascript Overrated? (Or how I learned to stop worrying and love Prototype & script.aculo.us)”. I never quite get around to doing enough JS work, instead finding other willing victims colleagues who are more into that kind of thing. But I’m definitely interested in being able to do more of the front end UI myself. So, I figured this tutorial would be useful.

Checking out my notes, I’ve discovered a few bits and pieces about Prototype & script.aculo.us that I didn’t know before. The highlights would be:

  • $$ has full support for CSS 1, 2 & 3 selectors. eg $$('table tbody > tr:nth-child(even)').invoke('addClassName', 'even') will select every second row of a table and give it the class ‘even’. Neater than doing some cycle type thing.

  • New with 1.5: DOM traversal. $('id').down() picks the first child, $('id').up() picks the parent. next() and previous() pick siblings. $('id').descendantOf('parent_id') returns a boolean.

  • $('form').focusFirstElement() does exactly what it says on the tin.

  • The form validation demo code he showed off looks really neat. It makes use of a (non-strict-HTML) format attribute, then does some validation on onsubmit. The actual validation functions are all added to the appropriate Element subclasses. Very neatly done. I’m wondering if anybody has done some work to integrate this with Rails model validations and make it more robust…?

  • Official JSON library breaks Prototype enumerables, so don’t use it! Doesn’t matter because Prototype implements everything anyway.

  • transition option for effects determines the function used to affect the dx/dy of the argument passed in to update. Apparently, sinoidal looks more natural for moving effects than linear, so that it accelerates & decelerates.

  • New in scriptaculous 1.7: Effect.morph() which will change from existing CSS styling to a newly specified one over a period of time. For example, grow a font size or move items around. Difficult to explain, but it looks pretty sweet. :) Best to use for mocking up an effect, because it has performance issues from parsing the CSS.

  • Firebug will actually show you the transitions happening (delayed, though). Inspect the element, then run the effect, and Firebug will show you the style attributes changing, highlighting them in yellow as they change.

  • Effects have an inspect() function to use from the Firebug console.

  • Element.addMethods() to put custom effects on elements (so that you can just do $('id').customEffect()) looks pretty powerful.

Umm, that’s about it, I think. To be honest, I was a little disappointed — the tutorial was pretty low bandwidth and didn’t introduce much I couldn’t have found by looking at the manual. Then again, I’m not sure what I was expecting…

One question I’d meant to ask since he mentioned it: Is there an idiomatic way of having an initialize() method in a subclass which calls the initialize() from its parent class? (The equivalent of doing super in Rails.) I’m not too fussed about a generic solution that works for every method, but one that at least works for initialize would be good.

Turns out caffeine is a substitute for sleep … so far

Well, I’ve arrived in Portland, Oregon. The journey was remarkably easy, albeit a bit dull. I made the mistake of saving my laptop for later on in the journey (when boredom had really set in) and discovered that the battery had already eaten itself. (On the way back, I’ll either use the laptop while I can, or remove the battery while it’s in transit.) The journey was Edinburgh → London Heathrow → Chicago O’Hare → Portland with about 19 hours of flight time and just 4 hours sitting in various airports waiting for connections. And 27 hours being of being awake. I think that’ll mitigate the jet lag somewhat, since I wound up going to bed around 01:00 local time and getting up at, well, a bit early at 06:00 but close enough to normal waking up time.

Speaking to my colleagues in the office back in Livingston at 09:00 local time when they were just finishing up for the day was really weird. It’s bizarre to think that back home, today is nearly over already when it’s not even lunchtime here!

Anyway, I’ve spent the morning wandering around Portland, just getting my bearings. I walked from the convention centre to downtown, just to figure out the distance — nice and short. And I’ve wandered back to the Lloyds Centre which seems to be the big shopping mall. The MAX Rail service is really handy (and free in the area I’d be wanting to use it!) so now that I feel I’ve got my bearings I’ll probably starting hopping on and off it as I need.

So now I’m trying to figure out what to do for the next couple of days. I definitely want to check out some of these microbreweries I’ve been hearing about. In fact, I think I’m going to be at the Tugboat Brewing Company, as recommended by the Planet Argon folks, from about 5pm tonight (Tuesday). I can’t see me surviving long, but I’ll definitely be there for a couple, if you want to join me. Just look for the mug on the sidebar of Notes From a Messy Desk wearing a brimmed hat and a Guinness St Patrick’s Day t-shirt. :)

On Wednesday evening, I’m planning to gatecrash the Joyent Geek Dinner (hey, I’m even a customer of theirs these days) and I’ll definitely be popping along to the dtrace BoF on Thursday evening too. But I should find something touristy to do on Wednesday during the day, and possibly for the rest of this afternoon.

Update I love that Portland has free wifi, through Metrofi. I don’t even (really) mind the adverts if that’s the tradeoff. I hate that their transparent proxy (for doing those adverts) breaks subverion-over-http. Pah! If you’re going to insist on doing transparent proxying, could you at least pass through HTTP verbs that you don’t understand verbatim?

RailsConf 2007

Well, that’s me packed, I hope. I’m just grabbing a coffee or three before I start my journey out to Portland for RailsConf 2007! The laptop has the latest Peepcode screencast: Javascript with Prototype.js; and a couple of the newest Pragmatic Programmers’ books: Release It! and Programming Erlang (not that I’m thinking seriously of switching to Erlang any time soon, it just sounds interesting, and I do like to learn a new language every year or so!). I’ve got a pile of paper books with me for when the laptop batteries give out.

The journey will be about 10.5 hours according to respective local wall clocks, but 17.5 hours elapsed time. I get in to Portland International (PDX) at 22:02 and, hopefully, can figure out the MAX-Rail system to get to my hotel, the Inn at the Convention Centre (which, I get the impression, is pretty basic, but since I’m only planning on sleeping & washing there, I’m sure it’ll do!), then collapse and hope I wake up sometime in the next 2 days! Then it’s just the strange local culture I’ll have to adjust to. :-)

Hrm, I wish O’Reilly had produced a PDF or something of the schedule, along with the abstracts. I would like to have printed that off and read it on the journey. If I’d thought about it further in advance, I could have taken the data from the web site and done so myself, but alas, no. Lazyweb request: I don’t suppose somebody else already has all the conference abstracts in one flat file that I could chown?

I’ve just checked out the weather; apparently it’ll be about 29°C today! Maybe I should have packed shorts instead of my kilt… (Umm, yeah, I don’t know if I’ll get the opportunity to wear it — that all depends if I’m invited to the cool parties! — but I do have my kilt with me.)

Anyway, all this is just my way of saying: Yay! It’s finally RailsConf and I’m on my way!

RailsConf Europe 2006: Unicode for Rails — Dominic Mitchell

This is the twelfth (and final!) in a series of articles of me writing up my notes from RailsConf Europe 2006. They are all first drafts, probably technically inaccurate and slanderously misquoting people. Let me know and I’ll fix them. You can follow this series of posts by looking at articles in the RailsConfEurope category.

Ruby (and therefore Rails) has a bad reputation for Unicode support. Dominic started by giving an overview of the various standards for character sets and encodings that led us to the current situation:

  • First there was ASCII (he never did mention EBCDIC) which used 7 bits and represented 95 printable characters, along with some control characters. It didn’t exactly cater for foreign languages, even other western languages that just have minor character variations like accents.

  • ISO-8859 was developed in the mid 80s with different code pages for different languages. Effectively this meant that a code point would represent a different glyph depending on the choice of code page. This made data interchange difficult.

  • ISO-2022-JP was created to represent Japanese characters. Its code points were multi-byte sequences with ‘mode switching’ which meant that you had to linearly process a string from the start — you couldn’t just jump into the middle because you wouldn’t know what mode you were in.

  • Windows-1252. This was a variation on the ISO-8859 standard, which used empty space (unused code points) in the code page to insert other characters. Like em-dashes and smart quotes. (Which is why you get weird characters when you copy’n'paste from a Word document…)

  • Now we have Unicode. It’s a 21-bit character set which means it has the capacity for about 2 million characters, of which around 10,000 are currently assigned.

Since Unicode code points can be up to 21 bits long, we need to find a way of encoding them. There are 3 possibilities:

  • UTF-32. Every character uses 4 bytes. It’s a dead simple implementation, but very wasteful because 11 bits (about a third) on each character are going to waste.

  • UTF-16. Pretty wasteful for Western languages because most of their characters can be stored in a single byte and it’s likely that every second byte will be null. However, it is commonly used on Windows and in Java.

  • UTF-8. This one is ASCII compatible for the first 7 bits which makes it backward compatible with existing ASCII text. Apparently it was Ken Thompson & Rob Pike that doodled this encoding system on the back of a napkin one day…

One of the features of Unicode is that single printed (or displayed) character can be composed of multiple code points. The generic name for a single displayed character is a grapheme, which can be made up of several glyphs. This allows you to construct combinations of characters that the Unicode authors had not foreseen. Like, for example, a lowercase ‘k’ with a circumflex.

Since we can compose characters in different ways, there’s a possibility that two strings could be the same, but represented by different sets of code points (glyphs). So we need a technique to normalise strings before comparing them. There are four different mechanisms specified in the Unicode standard, but the W3C has stated that NFC is the one everybody should use. It composes graphemes into single glyphs if at all possible.

So, that’s what Unicode is all about. Convention is: use UTF-8 and NFC. Sorted.

What about getting Unicode support in Rails? As far as the browser goes, HTML forms are generally sent back in the same encoding as the page’s character set. So make sure you set your HTML pages’ character set to UTF-8, usually with:

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

somewhere in the head of all your HTML pages. You might also want to configure your web server to explicitly tell the browser that the character set is UTF-8 too (eg AddDefaultCharset UTF-8 in Apache). There is the accept-charset attribute on forms, but apparently it is not well supported in browsers.

In Ruby, setting $KCODE="utf8" early in your config/environment.rb will switch you into Unicode mode. From there, there’s limited support for Unicode strings: regular expressions will be Unicode-aware if you pass in the ‘u’ flag; and pack/unpack will work with Unicode strings. There are a number of different packages to provide additional Unicode support, the most promising of which (to me) sounds like character-encodings. It claims to be similar to how Unicode support will be in Ruby 2.0.

I did pick up another useful thing that I want to incorporate into an application I’m writing just now: use iconv to turn MS ‘smart’ quotes and other funny characters into UTF-8:

Iconv.new("UTF-8", "WINDOWS-1252").iconv stuff

From the database perspective, you need to set the encoding on the database when you create it, which would be something along the lines of:

CREATE DATABASE foo CHARACTER SET utf8 COLLATE utf8_general_ci;

and you need to set the encoding of the connection to the database, in the appropriate stanzas in config/database.yml:

production:
  user: root
  host: localhost
  encoding: utf8