• "The Bullet gem is designed to help you increase your application’s performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries), when you’re using eager loading that isn’t necessary and when you should use counter cache."
  • "In the golden age of BASIC, it was easy for anyone to write a program. Now we offer you this exact same capability, but this time with the advanced features of the Nintendo DSi™ system… Many programs are included to ensure that you can fully enjoy using BASIC. The included programs were also written in BASIC, so you can add new features to them in order to enhance your games. You can also take the programs and data you create and convert them to QR codes that can be shared with friends who also have Petit Computer on their Nintendo DSi systems. (Programs included: 12 feature samples,5games, a character picture tool,a background screen creation tool,a graphics tool,and a picture-drawing tool.)" Interesting – especially the music-creation stuff, as Create Digital Music proved.
  • "Everyone seems to be compiling lists of the best games of the decade, so here, with minimal special pleading or argumentation, is mine." Steven Poole's list is good, though two entries for the MGS series is one too many, IMHO. I'd swap one of them for something Harmonix-flavoured.
  • "This is a list of old game releases. These games were priced at nearly $50 a year ago, now probably a lot less. Why buy a new game when there are plenty of fun games out there worth renting or buying for less?" Games released twelve months ago this week, by Andre Torrez. He's right, you know – games don't have to be about nowness all the time.
  • "It’s pretty difficult to talk about what you’ve got wrong. When you’ve been working on something like School of Everything very intensely for two years you can’t really blame the mistakes on anybody else. But the truth is that we need to rethink because we haven’t managed to make the idea financially sustainable yet." And so they're doing out loud. It's a big move; I hope it works out OK for them, because they're definitely Good People.
  • "In the desert 100 miles northeast of Los Angeles is a suburb abandoned in advance of itself—the unfinished extension of a place called California City. Visible from above now are a series of badly paved streets carved into the dust and gravel, like some peculiarly American response to the Nazca Lines (or even the labyrinth at Chartres cathedral). The uninhabited street plan has become an abstract geoglyph—unintentional land art visible from airplanes—not a thriving community at all."
  • "On the contrary, the quick wins of some big ticket consulting sessions sell our discipline short by pretending that design is some magical elixir that can be poured into a situation and zammo everything is fixed up. Like accounting, medicine, and just about every other profession, design is a practice which is persistently useful at regular intervals. If anything, during this transitional period where business and government are slowly coming to terms with the potential yield of having design as an integral part of the conversation it behooves us to collectively seek longer engagements, not shorter." Some excellent stuff from Bryan Boyer.
  • "As a real-life pro skater, you might spend three hours out of every day practicing. Three hours trying new tricks, screwing up and the ground abruptly slipping out from under you. Imagine living your life in that fog of frustration, embarrassment, adrenaline and pride. Now let's imagine you got really sick, swallowed, like, nine Paracetamols and passed out in bed. THPS2 is what you'd dream." Quinns goes misty-eyed over THPS2, and he is right to do so. It was wonderful.
  • "It’s pretty common to want SQL queries against a particular table to always be sorted the same way, and is one of the reasons why I added the ordered scope to the utility scopes gem… Well now you can specify default ordering, and other scopes, in edge rails directly in your ActiveRecord model." Hurrah!
  • "With the recent addition of dynamic scopes, however, you now have a way to both quickly specify query logic and chain further conditions. The naming works in the same manner as dynamic finders and the chaining works in the same fashion as conventional named scopes." Ooh. New in Rails 2.3, and passed me by a little.
  • Really rather good series of tutorials on the FCE4 basics.
  • "So here's my theory: WoW doesn't resemble a film. It resembles, rather, a medieval cathedral. And a magnificent one: it is the Chartres of the video-game world. Like a cathedral, it is a supreme work of art that is, on a brick-by-brick basis, the creation of hundreds of artisans and craftsmen, many of whom will be long gone by the time it comes to completion; indeed, since WoW is in a state of permanent expansion, it may not ever be "complete". All those programmers are the modern-day equivalent of stonemasons, foundation-diggers and structural engineers."
  • "This December, the Eisner-winning artists behind such acclaimed projects as "Sugar Shock," "Umbrella Academy," and "BPRD: 1947" will present "Daytripper," their first original title from DC Comics' Vertigo imprint… The comic, which jumps around moments in the life of Brazilian aspiring novelist and newspaper obituary writer Brás de Oliva Domingos, will follow the main character as he explores and evaluates his own existence and attempts to discover the answer behind the mystery of the meaning of life itself." Oh. This sounds good!

Connecting Rails to legacy databases isn’t actually that hard – depending on the database you start out with. Recently, we needed to perform some statistical analysis on a large Movable Type database. Rather than wrestling with endless SQL queries at the prompt, it made sense to abstract out a little and build some kind of modelled front end to the statistics.

The most obvious tool for me to use was Rails; I’m familiar with it, I like the way ActiveRecord works, and it means that I can poke around the database from script/console if I need to.

The reason this turned out not to be too hard is because whilst Movable Type doesn’t conform to Rails’ opinionated ideas of what a schema should look like, it is still a well-designed and normalised database. Because of this, we can teach ActiveRecord to understand the database.

First of all, we start by creating our models: for our needs, Blog, Comment, Post and Author. We generate them in the usual manner – script/generate model blog. Once we’ve done that, we delete the migration files in db/migrate it creates, because we’re not going to use them.

Next, we point config/database.yml to the Movable Type database.

And then, we build our relationships thus:

class Blog < ActiveRecord::Base
  set_table_name "mt_blog"
  set_primary_key "blog_id"

  has_many :entries, :foreign_key => "entry_blog_id", :order => "entry_created_on"

class Entry < ActiveRecord::Base
  set_table_name "mt_entry"
  set_primary_key "entry_id"

  has_many :comments, :foreign_key => "comment_entry_id"
  belongs_to :blog, :foreign_key => "entry_blog_id"
  belongs_to :author, :foreign_key => "entry_author_id"

class Comment < ActiveRecord::Base
  set_table_name "mt_comment"
  set_primary_key "comment_id"

  belongs_to :entry, :foreign_key => "comment_entry_id"

class Author < ActiveRecord::Base
  set_table_name "mt_author"
  set_primary_key "author_id"

  has_many :entries, :foreign_key => "entry_author_id"

The set_table_name method tells the ActiveRecord class what table to look at, and the set_primary_key method does exactly what it says on the tin. (It also makes sure that #to_param works correctly based on whatever our new primary key is, which is handy). Beyond that, we simply have to specify the foreign keys on our relationships and everything plays ball; we can now access blog.entries just as we do with a typical Rails setup. It’s now easy to write the rest of our Rails app – model methods, controllers, views – just as we normally would. We’re just using the MT database to pull out our data.

And if you’re wondering: yes, it made the manipulation a lot easier, and a few hours poking at the console began to yield some interesting algorithms to apply.

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

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.