So, in response to an earlier post, “mexx” asks:

Let’s say that I have a class BigTree and I have a string ‘big_tree’ how do you get the string translated to ‘BigTree’ so that I can use this translated string the way you showed?

That’s a fun challenge. Well, as I’ll later show, it’s a problem to which I already know the answer. But I gave it a shot, and came up with this – my first genuine, off-the-top-of-my-head one-liner (and I wasn’t golfing):

def camelize(str)
  str.split('_').map {|w| w.capitalize}.join
end

That’s a bit cryptic. To decode it, if Ruby’s not your first language:

  1. Take a string
  2. Split it on underscore characters into an array
  3. Capitalize each item in the array in turn (which I do by mapping the array to a new array, with the built-in String method capitalize)
  4. …and then join the whole array back into a string

Unfortunately, that works for mexxx’s example – big_tree will map to BigTree but it’s certainly not true for all possible classnames.

But, as I said earlier, I already know the answer to this. It’s part of Rails – specifically, it’s in the Inflector component of ActiveSupport. Go to the API docs and look for “camelize”. Most of the Inflector components are dependent on each other; camelize, fortunately, is only dependent on itself. And it looks like this:

def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
  if first_letter_in_uppercase
    lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
  else
    lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
  end
end

That looks a whole lot more convincing and generic. And I think that’s your answer, mexxx. So don’t thank me – thank the Rails core team. There’s lots of useful basic Ruby tools hidden in the Rails sourcecode – it’s always worth an explore, if only to find out more about how it does its stuff.

To cut a long story short: the slides for the talk I gave earlier this week are now available. You can find out more about the talk on the talks page of this site, or you can download the PDF (1.5mb). It should be fairly self-explanatory.

(A brief summary for those of you unable to scroll or click: it’s a client-side-developer’s perspective on Rails, and how to integrate client side development into the build process).

I’m going to be speaking tonight at LRUG. The talk is called “Ruby on Rails from the other side of the tracks“, and it’s about how client-side developers fit into Rails, and how you (as a back-end developer) can work with them rather than against them. If that sounds interesting (or, more to the point, you want to hear Tiest talk about Domain Specific Languages, which should be great), do come along.

Didn’t notice this when it happened (because it didn’t necessarily appear on the frontpage) but… my review of David Black’s Ruby for Rails has now gone live over at Vitamin.

My first piece of technical writing. It’s a good book, too – clarified an awful lot about the hierachy of classes within the language, and explained the nuances of Ruby dynamism very well; strongly recommended to anyone coming to Ruby (through Rails) afresh, whether you’re an experienced programmer or not. I hope I conveyed that in the review.

Matt posted a really elegant piece of code today that generates Graphviz files (suitable for importing into OmniGraffle) of your Rails ActiveRecord relationships. It’s pretty neat, and certainly handy for getting to know foreign codebases.

There’s one neat trick in there, though, that I wanted to expand on, as Matt breifly chatted to me about the problem earlier today over IM – namely, how you get the actual class object so that you can call reflect_on_all_associations on it.

In Ruby, it’s easy to dynamically call methods – you can put the name of the method into a string, and then simply run Object.send(methodname). Getting the actual Class Object for a particular object – that’s much trickier.

There’s the obvious solution of using eval. So, to get all the methods on your classname:

classname = 'Integer'
eval classname + '.methods'

but that, of course, is pretty nasty and kludgy. This is Ruby, after all; there’s got to be a better solution, right?

There is. If you look in the Pickaxe, you’ll find that Class Names Are Constants:

All the built-in classes, along with the classes you define, have a corresponding global constant with the same name as the class.

So this means that by passing the class name to the const_get method on the Kernel module, we’ll confirm if a class exists with that name (eg Integer). Then, because that constant is really a reference to an object of the same name, by sending a message (the method calal) to the constant, it will be passed on to the object and run (which is the best way I’ve got of explaining this). Job done! To use the previous example:

classname = 'Integer'
Kernel.const_get(classname).methods

Which is, you must admit, a bit more elegant and maintainable than the evil that is eval.

Problem: there’s no Velocity (VTL) bundle for Textmate.

Solution: write one yourself.

I’m currently working on a basic Velocity bundle for Textmate. We use it as a templating language at work, and, let’s face it, Textmate is an awesome editor with many, many ways to make your life easier. Given that it’s listed as a bundle people might be interested in… I’d better get started on it, right?

If you’re interested, leave a comment or drop me an email. So far I’ve got some basic function and syntax highlighting, along with autocompletion of some common constructs. Once it’s more finalised – and has been built in accordance to the VTL spec, not just the way I write it, I’ll start putting out releases.

(And if none of this makes much sense: Velocity/VTL is a templating language for Java web-apps. It’s one of the least sucky Java templating languages, apparently, but it’s not as mature of fully-featured as, say, Smarty.)

It’s a strong title for a post, I know, but having discovered that two friends didn’t know this at last night’s LRUG, I wanted to share it.

Let’s put this in bold for impact.

When you add <%= javascript_include_tag :defaults %> to the top of your Rails layout, you’re adding 146kb to your page load.

And, being Javascript, that all loads serially. This is slowing page load down a lot.

Now, I’m sure if you’re building a whizz-bang AJAX app you need all that. But I reckon a lot of Rails projects don’t use anywhere near all that. So throw some out!

The Scriptaculous libraries are quite big: dragdrop.js is 30kb, controls.js is 29kb, effects.js is 34kb. If you don’t need that lot, get rid of it. prototype.js alone is 56kb. The case for the Prototype library is easier to make… but if all you’re doing is some simple DOM scripting – show/hide, for instance, do you really need 56kb of library functions to do it? Or can you do it in < 10kb with some home-made functions? If so, strongly consider doing that. And if you’re not using any Javascript in your application… why have you get any of it in there? It can all go – that’ll speed page load up no end!

I’m not saying there’s no place for this stuff – there is. Should it be included in Rails Core? Absolutely. I just don’t think that it should be called the “default” option; <%= javascript_include_tag :all %> would make a lot more sense. And by sticking it into the basic scaffolding layout, it becomes a part of many people’s first experience with Rails – and they assume it’s default behaviour. And so I also think it should be left out of scaffolding – perhaps replaced with <%= javascript_include_tag "prototype", "application" %> at the least.

User experience, usability, and accessibility aren’t just about the content or code of the page; they’re about how the user experiences the page. If it takes an age to load, it makes the app less usable. If you’ve got huge page size, you’re excluding anyone on a slow connection. So next time you’re skeletoning out a Rails app, take a moment to think if you really need any Javascript. If you don’t, <%= javascript_include_tag :defaults %> can go straight in the bin. Then, when you come to progressively enhance your app at the end with Javascript (which is, let’s face it, how you should be doing it), you can include only the files you need – and keep your users happy at the same time.

One thing most web applications need is a static page template. Now, whilst the page content might be static, the template itself might need to be dynamic – either because it’s going to change in future, or because you’ve got dynamic user information that appears in the tempalte.

So the most obvious way around this is the static controller. Dead easy, this: generate a new controller called static (or whatever you want). Then just write views for it named after pages you want. For instance: your about.rhtml file can contain all your “about” information. Then, when you hit up /static/about (to use the default routing), you get your static content, without having to make a whole page from scratch in public_html. You could even write a new 404 page on this controller.

All that remains, once it’s working, is to write some dedicated routes, and then the “static” controller can be hidden from existence – just route /about to :controller => "static", :action => "about" and you’re done. No need to write any controller logic at all!

Going on from there: one view I’ll always add to that template is the “foo” action.

So: when you’re mocking up a page, you’ll probably use lots of dummy links. Everyone expects this, because it’s obviously just a flat mock. But when you mock up an application, and show it to stakeholders in a working state, they click on things, and wonder why they get ActionController exceptions when it breaks. Also, they wonder why the link that breaks stuff is always /foo.

Obviously, it’s because I’ve left link_to "/foo" all over the shop. Have no fear: the easy way around this is to route /foo to :controller => "static", :action => "foo", and then write a static page called foo.

When you do this, the page should explain that it represents functionality that hasn’t been added yet, but will be added soon, and that the developers haven’t forgotten it.

This (from experience) reassures stakeholders that the thing that is not working will be working soon. It also means that when they do find “grey screen” errors, it either means that something’s genuinely broken, or it means that the developers really have forgotten something. Time to update that link to point to foo.

It sounds trivial, but it turned out to be an effective communication of diligence on the developer’s part, and saved much time in meetings explaining that “yes, we’re working on that”. Consider it, next time you’re developing for external stakeholders.

Sometimes, when you’re building a Rails application, you want to generate different relationships to the same model – or, rather, multiple relationships to multiple perspectives on a model. You can tell ActiveRecord to override the expected class name, but you can also use this technique to create “subsets” of classes for relationships, too. It’s worth remembering that ActiveRecord can generate these for you. By doing the query in the database, rather than filtering afterwards, your application will run faster.

As you can see from that explanation, I’m not exactly the greatest developer, so this is probably best explained with an example from life.

I’m currently working on a CMS – yawn yawn, I know. Anyhow, in this CMS, we have articles, and an Article has_many :comments. Obvious one-to-many relationship, fine. However, comments may or may not be spam, marked by the attribute is_spam. So whilst article.comments will return all the comments on a particular article, it’d be nice to have a class method that returns all the clean comments; article.clean_comments, for instance.

My first stab at this was to add the following method to the Article class:

def clean_comments
  output = []
  self.comments.each do |c|
    output << c unless c.is_spam
  end
  output
end

which is, I suppose, passable idiomatic Ruby, and which does the job; we build an output hash of objects unless the comment is spam. The problem is that if you have, say, an article with a thousand comments - of which 990 are spam, we end up having to generate 1000 objects from the database, and then filter them with Ruby. It'd be faster to select only 10 from the database in the first place, right?

We can do that by defining a new relationship. In our Article model, under has_many :comments, we can add this:

has_many :clean_comments,
         :class_name => 'Comment',
         :conditions => 'is_spam is null',
         :order => 'created_at'

Bingo. That extra has_many allows us to refer to article.clean_comments, and it'll do so directly from the database via SQL. This is a fairly simple example, and I do recommend looking up has_many and has_one (which has similar capabilities) in the Rails API documentation. There always seems to be more depth with Rails than you initially expect, so it's worth digging a little deeper - and you'll make your code leaner, quicker, and better as a result.

Getting Naked

05 April 2006

So apparently it’s Naked Day today. Strip away your CSS, show off your white bits.

It’s only right I join in, given that my day-job now is writing the leanest, most accessible XHTML/CSS I can, and that, more to the point, I spent a fair while trying to make this site vaguely accessible if you can’t see the stylesheet. So here we are. Raggedy-bits and all. The stylesheet will automatically switch back to its “International Klein Blue” look on the 6th April.

(The site is, of course, now back to normal)