This is where I tell you stuff

A blog about code, adventure, grapefruit beer and me

Single-Table Inheritance vs Class Table Inheritance

Last week I came across a blog post featured in Ruby Weekly called Better Single-Table Inheritance, by Nathan Long. On it Nathan described his experiences coming up with a sane way to do STI on Ruby on Rails.

Single-Table Inheritance

For those of you not familiar with the technique: STI consists of reusing the same table to express a variety of models which share similar attributes. So instead of having a database like this one:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
ActiveRecord::Schema.define(:version => 20130203210553) do

  create_table "people", :force => true do |t|
    t.string :name
    t.string :shoe_size
    t.string :place_of_birth
    t.string :blood_type
  end

  create_table :scientists, :force => true do |t|
    t.string :name
    t.string :shoe_size
    t.string :place_of_birth
    t.string :blood_type

    t.string :university
  end

  create_table :chefs, :force => true do |t|
    t.string :name
    t.string :shoe_size
    t.string :place_of_birth
    t.string :blood_type

    t.string :hat_size
  end
end

It look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ActiveRecord::Schema.define(:version => 20130203210553) do

  create_table "people", :force => true do |t|
    t.string :name
    t.string :shoe_size
    t.string :place_of_birth
    t.string :blood_type

    t.string :type # => Needed for the ORM to know which kind of object its dealing with.

    t.string :university # => The Scientist field(s)

    t.string :hat_size  # => The Chef field(s)
  end
end

Looks better, right?

The problem

I’ve always liked the concept of STI and felt that it was a fairly elegant way to have models that are persisted on a database inherit from each other, but what has always bothered me is how the database ends up being really ugly. What happens is that for all your, say, Scientists stored in your People table the recipes field will hold a NULL value. The database ends up being a mess, and you can’t quite make sense of the data structure just by looking at the schema anymore.

To avoid this Nathan’s post proposed the following solution:

Put common attributes in a single table, non-shared attributes in separate tables with foreign key references, and use object delegation so that each model transparently pulls what it needs from both.

Which I initially liked, the problem came up when I scrolled down and saw this implementation of that idea for ActiveRecord

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Use in subclasses like:
# delegate_details :win_ratio, :tanning_time, to: :wrestling_details
def self.delegate_details(*attributes)
  options = attributes.extract_options!
  association_name = options.fetch(:to) {
    raise ArgumentError.new "You must specify the name of the details association"
  }

  define_method association_name do
    super() || send("build_#{association_name}")
  end

  attributes.each do |attribute_name|
    # Getter, setter, and boolean getter (in case it's a boolean attribute)
    def_delegators association_name,
      :"#{attribute_name}", :"#{attribute_name}=", :"#{attribute_name}?"
  end
end

The horror. I don’t know about everybody else, but I dread finding this kind of stuff on an application I have to work on. So yes, while I liked the idea I found the implementation to be extremely unintuitive and I’d be willing to bet that this is because of how ActiveRecord does things.

You have to also do some weird stuff to add a foreign key in your models and even have to keep writing code to make something like Scientist.where(university: 'Stanford') work. Not good.

Ditching ActiveRecord

Even with those problems I still liked the idea and wanted to see if I could find a cleaner way to implement it, I decided to use Sequel instead of ActiveRecord, because… well: I like Sequel and this is a simple thought exercise. What I found during my research to do this made me like it even more.

The solution: already a thing

I didn’t know about it before, and I’m super happy I took the time to read Nathan’s post and found out about this: The approach he came up on his own is a known technique called Class Table Inheritance, what’s even better is that Sequel already has a plugin that implements it.

By doing something as simple adding a plugin configuration line and adding foreign keys to each class that needs to inherit from another I have a perfect integration of multi-level inheritance in the ORM that allows me to query the database without any further problem. This code works:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
require 'sequel'

DB = Sequel.connect 'sqlite://database.db'

class Person < Sequel::Model
  # has name, shoe_size, place_of_birth, blood_type
end

Person.plugin :class_table_inheritance, key: :type

class Chef < Person
  # has hat_size
end

class Scientist < Person
  # has university
end

class Physicist < Scientist
  # has lightsaber_color
end

And the schema

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Sequel.migration do
  change do
    create_table :people do
      primary_key :id

      String :name
      String :shoe_size
      String :place_of_birth
      String :blood_type

      String :type
    end

    create_table :chefs do
      foreign_key :id, :people
      String :hat_size
    end

    create_table :scientists do
      foreign_key :id, :people
      String :university
    end

    create_table :physicists do
      foreign_key :id, :scientists
      String :lightsaber_color
    end
  end
end

The result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Scientist.create(name: 'Alan Turing', shoe_size: '41', university: 'Cambridge')
# => #<Scientist @values={:id=>1, :name=>"Alan Turing", :shoe_size=>"41", :place_of_birth=>nil, :blood_type=>nil, :type=>"Scientist", :university=>"Cambridge"}>

Chef.create(name: 'Guy Fieri', shoe_size: '45', hat_size: '12')
# => #<Chef @values={:id=>2, :name=>"Guy Fieri", :shoe_size=>"45", :place_of_birth=>nil, :blood_type=>nil, :type=>"Chef", :hat_size=>"12"}>

Chef.create(name: 'Guy Fieri', shoe_size: '45', hat_size: '12')
# => #<Chef @values={:id=>3, :name=>"Guy Fieri", :shoe_size=>"45", :place_of_birth=>nil, :blood_type=>nil, :type=>"Chef", :hat_size=>"12"}>

Person.all
# => [#<Scientist @values={:id=>1, :name=>"Alan Turing", :shoe_size=>"41", :place_of_birth=>nil, :blood_type=>nil, :type=>"Scientist"}>, #<Chef @values={:id=>2, :name=>"Guy Fieri", :shoe_size=>"45", :place_of_birth=>nil, :blood_type=>nil, :type=>"Chef"}>, #<Chef @values={:id=>3, :name=>"Guy Fieri", :shoe_size=>"45", :place_of_birth=>nil, :blood_type=>nil, :type=>"Chef"}>]

Scientist.first(university: 'Cambridge')
# => #<Scientist @values={:id=>1, :name=>"Alan Turing", :shoe_size=>"41", :place_of_birth=>nil, :blood_type=>nil, :type=>"Scientist", :university=>"Cambridge"}>

Works perfectly, without doing any magic and exactly as you would expect it to.

Conclusion

I don’t want this to look like I am bashing Nathan’s post, I think the idea is great, the fact that it is a known technique does not take any merit from he coming up with it particularly in the Rails world where STI is so often joked about. Thanks to his post I was able to learn something fairly cool and play around with Sequel. This post is merely a recolection of the research he prompted me to do.

In the end: Class Table Inheritance is pretty awesome, and I look forward to be able to implement this on a real application, using Sequel, obviously.

Eurucamp 2012 - Berlin

Okay, a pretty crazy weekend marked the end of a few absolutely crazy weeks for me, so I wanted to write a few lines about it. Last weekend I presented a talk titled “Modular vs Monolithic Software: No Holy Grails” at the fantastic conference Eurucamp, were I was lucky enough to be accepted as a speaker alongside some really fantastic rubyists.

The Venue

The conference was held at a fantastic place called Lake Muggelsee, just outside of Berlin, with tons of trees and a great vibe. Really just what I needed to unplug from a last couple of very demanding weeks at work.

The Conference

The conference was just amazing, the atmosphere wasn’t that much of a serious, extremely work oriented conference as much as a more familiar, fun and cheerful, a good percentage of people were calmly sipping beer while listening to the talks, there first day consisted almost exclusively of wonderful workshops on topics such as JRuby, Rubinius or just basic Rails usage, so there was pretty much something for everyone.

We even had the opportunity to have a few hours of free time on saturday to enjoy the great weather and location, there were organized biking trips, martial arts workshops, ultimate frisbee games and more. Pretty awesome indeed :)

The talks were incredible too, and although there was wonderful material everywhere I have mention specially ”Superheroes can do it and so can you!” by Florian Hanke and ”All You Need Is Love” from Isaac Wolkerstorfer and his wife Joan Wolkerstorfer, in both cases their deliveries of their fantastic materials was incredible, so big thanks to them for such amazing and inspiring talks. Finally: Txus Bach’s ”Polyglot Rails Applications with Rubinius” was super interesting as well, and gave food for thought on some fascinating concepts to play with.

Yeah, a crapload of people, amazing :)

My Talk

I have to admit I was a little nervous about my talk when I started, I was standing in front of nearly 200 people, with some insanely smart guys paying attention, which was a little intimidating. I think I did ease into my own topic after the first few minutes anyway, and to be completely honest at that point I didn’t even think much of anything, but just focused completely on explaining the topic of my talk to the best of my abilities.

It even looks like I know what Im talking about!

Many people had asked me about my talk beforehand, so I guess there was interest in the topic itself, I also had some really good feedback on twitter and a wonderful question from one of the attendees that I was lucky enough to have a good answer to. All in all: I think the talk went well, specially considering that it was my first time presenting. I did feel that I could have done stuff a little bit better, but I suppose that happens to everyone, I am happy with how it turned out and the feedback I got from it. Although to be honest I did have to change into a pair of shorts and jump into the lake immediately after the talk to take the edge off. :)

You can check the slides for my talk at the bottom of this post

Aftermath

I got to meet (or spend more time with) some really interesting people, the general atmosphere of the conference was incredibly cheerful and I think that added up a lot to the whole experience, most people seem to be having the time of their lives (me among them) so I think the conference organizers can sit back and relax on a job incredibly well done.

I’m definitely looking forward to the 2013 edition of the conference and try to attend. All in all it was a tremendous experience for me and it will definitely be remembered dearly. :)

Nick has a hilarious look on his face

Slides for the talk

On Git Commits and Programming Style

I recently had to send an email to our customer (and their developers) regarding mostly git usage and general Ruby coding style on our project.

The list borrows standard concept from many places and experienced git users and ruby developers will most likely know most of its points, but I was told it would make a good blog post, so here is an adaptation of the email.

git

On Git commit history:

  • Commit history is important, it’s even more important when we have a serious problem (IE: need to roll back changes for example). So make sure your commit messages are explanatory of what changes you introduce.
  • Don’t be afraid to use git commit --amend locally, I for example tend to forget about it and commit a lot of ‘debugger’ lines. So what I do is delete the lines, git add . && git commit --amend will fix the commit, so it will never get to github. (Important Note: never ever do –amend after you have already pushed to github. Or stuff will get scary – if you do this you’ll need to force push to github later, and it’s possible that you delete commits by other people)
  • Following the same reasoning: the first line of a commit message shouldn’t be longer than 50 characters. So as to keep it brief and easily parseable when you are reading through the commit history. If you need to talk more in detail about what you are doing (it happens a lot, and it’s not bad at all) do git commit without -m, so it goes into vim, and then write a short first line, leave an empty line and then describe the commit more in detail.
  • Don’t mix stuff, if you have a lot of changes do atomic commits only of the relevant files or else it gets really difficult to rollback only one feature, for example. Always think: “If I had to do a release NOW and this didn’t work: can I roll it back easily?”. If the answer is yes then you should be good to go :).

If you are working with Heroku

  • Don’t ever clone from the heroku repo, clone from the github repo and maintain that as origin, remember that we don’t use Heroku as version control, so make sure all your latest stuff is on github. There should never be a commit on heroku that was not in github first.

Ruby/General programming:

  • CSS in the views is a no-no.
  • Always use two-space indentation (soft tabs), make sure your editor does not insert tabs instead of spaces, as that might look different on different editors.
  • Same with JavaScript, a little is ok, big stuff goes into its own file (and in coffeescript, if possible).
  • Trailing spaces: I will murder you in your sleep.
  • Don’t leave empty lines at the end of a file. It gives me micro-seizures.
  • Never comment code and leave it there, we have git to remember our stuff, just delete it!
  • Always indent properly.

There is a styleguide for ruby (made by the guys at github) linked below that is more or less consistent with the style we have at Cubox (and with the standards on the Ruby community in general). Please read it, it’s only about 5~10 minutes and definitely worth it. :)

Further Reading

How to Get Good Developers

So for some unknown and weird reason I was contacted last week by someone from recruiting on a company that shall remain nameless, their intent wasn’t to hire me (or maybe it was, but they didn’t say it) but for me to give them advise on how to get in touch with highly skilled Ruby developers in Europe. They mentioned that I apparently lived there at some point and also misspelled my first name, which was really annoying.

I was bored today and felt like writing a response with some good advise, not really for their sake, but to try and help a bit to create a good ecosystem for programmers to work on, what follows is my reply, which I wrote a moment ago. I will just paste it here in the hope that it might be useful for other Recruiters. And maybe save myself a few emails in the future. :)

The email

I’m sorry I took a long time to answer your email, it was weird receiving it. Allow me to point which parts of it didn’t make much sense before giving you some advice on how to get in touch with good Ruby developers. :)

I haven’t really ever been to Europe, ever, and I only very recently spent about two months in the USA, also, you misspelled my first name, which let me tell you is a pretty horrible selling point. You need to take care of that stuff, specially since most good Ruby developers are pretty spoiled from a really favorable (for us) market right now, and used to be treated as highly valuable people are. Be careful about the small details, most of us have at least mild OCD and tend to notice this stuff. It’s annoying.

On to the advice you need: If you want good developers there are some main things you need to do:

Make yourself present at conferences.

We really pay a lot of attention to them, and highly trained developers attend those conferences either as speakers or attendees, try sponsoring a few for a start, or pay for a drinkup for the conference attendees after the event is done, EuRuKo (the last European conference held in Amsterdam recently) was on every Ruby developer twitter feed, your logo being everywhere and you being nice to people will tell us the two main things we want to know from a company before joining it: you are willing to give back to the open source community and you are fun and relaxed to work with. That’s really important stuff.

Pinpoint developers from open source projects an reach out to them.

Do your research, find out about good open source code in github, who maintains it, who originally wrote it, who contributed, don’t do stupid stuff like trying to get the original creator of Ruby on Rails as a “Ruby developer”, people in the open source world tend to be above average programmers, mainly due to their code being public and peer reviewed by a lot of other developers, we all learn a lot from that experience and grow to be the strong technical people that you need.

People with passion for what they do that will the extra mile on their own free will, because we feel proud of our code and want our products to succeed, being a programmer is much like being a gardener, or an architect, or some other form of art, only (for me at least) better. Because we spawn things with our minds and hard work and to see our brainchilds succeed is one of the greatest sources of joy we find. You want people with that sort of passion.

Spoil your developers (maybe not that much, but at least a little)

For better or worse most good developers today are really spoiled by the companies hiring them, and we’ve grown used to that, because of that it is highly unlikely that me or any developer that is happy leaves his or her job, and it’s very likely that a developer who feels mistreated, be it lack of respect for his work, considering him/herself underpaid or whatever other such thing will leave fairly quickly for greener pastures. The market has need of us and we are used to it. It’s just a fact that companies need to deal with these days.

Allow remote work

This is unfortunately just a no-brainer for you, most developers have their lives and the possibility of working remotely. Having a distributed team introduces some difficulty in team management but also gives you a much larger pool of suitable candidates, specially highly skilled developers, they can work for good companies from home, if they can’t do so for your company they are likely to not be interested.

I think those are the main facts, of course they don’t particularly apply to European developers, but Asian, South American, you name it. Wish you the best of luck with your company. :)

Migrate Your Blog to Octopress Using planet.rb

So a few days ago I manned up and decided to finally write planet.rb, mainly because I need to have a way of merging several blogs into one in a tidy way. This evening (while on a furious caffeine high) I thought of a slightly different application for the gem.

Octopress is awesome, and you should use it.

In the last few weeks I’ve been using Octopress a lot, its a fully customizable blogging engine that just gives you controll of everything. It’s also powered by the mighty Jekyll, the gem that is also responsible for github pages.

The process to set up Octopress is simple, and described perfectly in it’s documentation, you basically install a few dependencies, clone the repository, and you are ready to start writing blog posts and deploy your blog to github or via rsync to a private vps.

That is kinda neat, but I’m using { wordpress || blogger || whatever }

Exactly, and you really shouldn’t, that’s where planet.rb comes into play.

Import your blog using its RSS/Atom feed

Once you have followed the Octopress Docs to the point where you already have a cloned empty blog, simply install planet.rb with

 gem install planet 
and run the following commands on the Octopress root directory.

1
2
▸ planet init
=> Created default planet.yml

You will want to open the planet.yml file and put only your blog feed (as an example, the feed for this blog is http://blog.poteland.com/atom.xml) and your name as author, you can just put an empty string (”) for your picture, as we won’t be using that.

We will also need to empty the author.html template file so that it doesn’t put up an unnecessary picture of you. Do it with this command

1
▸ > source/_layouts/author.html
1
▸ planet generate

That’s it! planet.rb will pick up your blog, process the posts and save them in Octopress’s source/_posts/ directory. After that continue with the Octopress setup guide, with all your posts already on it. Congratulations on joining the Octopress community! :)

I Made a Pretty Gem - Planet.rb

I’ve been hurting to write this ever since we had the idea of creating a Planet for Cubox, a planet is - for those who have never heard the term - a static site generated from all the posts in a given set of blogs, it’s pretty awesome, it allows organizations to have a place with all their coder’s posts on them without having to duplicate each post on both the company blog and the coder’s.

Update

Since I published this I’ve been working like crazy on it, and some of this documentation might be outdated, please check the github repo for the latest available documentation. :)

Wasn’t this invented like a million years ago?

Yes, yes it was, this is nothing new, important examples of this concept can bee seen at Gnome and KDE planets, so I figured that there would already be solid technology behind this. I set out to get that code and implement it on our own shiny and geeky planet.

And then I saw the code.

I imagine both Gnome and KDA have moved on on their planet’s code, but I wasn’t able to find anything newer than planetplanet.org’s implementation. A codebase that hasn’t been touched for years (it requires python 2.2 for christ sake!!!)

I set out to patch the code to our needs, I created a github repo for planetplanet’s codebase and started working into adding some features, however I quickly found that it’s templating capabilities where horribly outdated, and frankly… well unusable, I love python, but I wanted to stab myself in the eye with the nearest fork while working with it, and it’s been theorized that eye stabbing is generally not good for your health, so I decided to rewrite the damn thing.

Shut up already! Show me this marvelous code you are giving me for free!

Allright, allright, shutting up now. Let’s assume that we have a shiny Octopress blog that we want to turn into a planet. This is what we will do.

1
2
3
4
▸ ls
CHANGELOG.markdown README.markdown    config.rb          public
Gemfile            Rakefile           config.ru          sass
Gemfile.lock       _config.yml        plugins            source

Install the planet.rb gem

1
2
3
4
5
▸ gem install planet
Successfully installed planet-0.0.1
1 gem installed
Installing ri documentation for planet-0.0.1...
Installing RDoc documentation for planet-0.0.1...

We want to go to the source directory and then create a basic planet.yml file that will contain your list of blogs

1
2
3
▸ cd source
▸ planet init
=> created default planet.yml

You will most likely want to edit this yml file (unless you really really like me and Cubox!), after you are done, run the generate command.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
▸ planet generate
=> parsing http://blog.poteland.com/atom.xml
=> parsing http://blog.cuboxlabs.com/atom.xml
=> Found post titled Cubox brings back Ruby meetups to Montevideo - by Cubox
=> Found post titled We're hiring - by Cubox
=> Found post titled rubydeps - New gem by Cuboxer - by Cubox
=> Found post titled Cuboxers at wroc_love.rb in Poland - by Cubox
=> Found post titled Open Source Projects - by Cubox
=> Found post titled Machine learning in perspective - by Cubox
=> Found post titled Cubox on finances - by Cubox
=> Found post titled So what is Uruguay like? - by Cubox
=> Found post titled Supporting this weekend's Rails Bugmash - by Cubox
=> Found post titled One App in the App Store - by Cubox
=> Found post titled A new website - by Cubox
=> Found post titled Google Chrome OS: Obvious to the point of being boring. - by Cubox
=> Writing 12 posts to the _posts directory

And that’s it! your _posts directory should be populated with all relevant posts from the blogs you’ve configured, and it’s ready to be deployed. :)

Where’s the code? Can I break it?

By all means! The code is public and lives on it’s github repo, suggestions (and better yet, patches!) are more than welcome!

A quick note about Jekyll.

Jekyll is awesome, and planet.rb can be easily used with it too, but I tend to favor Octopress as a simple-setup superset of Jekyll. Also, if you are using it, you probably don’t need my help to set your Jekyll planet up ;)