giant robots smashing into other giant robots

We are thoughtbot. We make web & mobile apps.

Tagged:

Comments (View)

A smattering of t-bot news

So, we just got word that the last chapter for our book has made it through the copy editing stages and has been delivered to ‘production’. We’ve got the proof of the cover, and we’re on our way to release it in September.

You can preorder it now from Amazon.com

Also, we’re almost up and running with our new New York City office. Located at 407 Broome St., we’re sharing space with the great folks at thehappycorp

Finally, we’d like to welcome our newest member to the thoughtbot team, Dan Croak. We met Dan while working with (for) him on National Gazette and we’re very happy to have him join us.

We’re continuing to look for excellent programmers and web designers (or people who want to be) for both our Boston and NYC offices, for more information go here.

Tagged:

Comments (View)

Our ActiveRecord book …and YOU!

Well, it has started to show up on the Apress website, so I believe that means there is no use in hiding it any longer. Jon and I (along with our co-author, Kevin Marshall) are currently hard at work on book for Apress, entitled Pro ActiveRecord for Ruby: Databases with Ruby and Rails.

The book will focus solely on ActiveRecord, both inside and outside of Rails, and seeks to be a complete reference for ActiveRecord.

Well, with that out of the way, I’m currently working on the “Common Questions and Howtos” chapter, which is the chapter that contains all of the juicy tidbits and edge cases that don’t fit well into their own chapters, and if anyone out there has any ideas of things they’d like to see covered there, I’d be really interested to hear them. I’ve currently got some info on using multiple databases, how to handle localization, using composite primary keys, using GUID/UUID keys, and some other things along those lines – I’d love to hear if there is anything you think might be of value for both new users, experts and everyone in between.

Tagged:

Comments (View)

A Convenient Squirrel Addition

This is probably something that should have been done sooner, but I didn’t get around to it and it wasn’t immediately important to us. Since it now is, I changed Squirrel’s call to ActiveRecord::Base#find to include all parameters passed in, even the extra hash variables find normally uses. While this isn’t terribly amazing on its own (although it does mean you can use :limit even though it doesn’t have Squirrel-specific syntax yet), it allows the usage of the terribly lovely paginating_find plugin.

posts = Post.find(:all, :limit => 10) do
    created_on > 7.days.ago
end

orders = Order.find(:all, :page => { :size => 5, :current => 2 } ) do
    customer.id == params[:customer_id]
end

Both of these will work as expected now. Well, the second one needs paginating_find installed, but you know what I mean.

As always, the repo is at https://svn.thoughtbot.com/plugins/squirrel

Tagged:

Comments (View)

When to create?

The “find_or_create_by” feature in Rails’ ActiveRecord is pretty handy – sometimes you don’t know whether you have the record you want, but you’re sure you want to create one if you don’t have it yet. We’ve used this in places where the system has a concept of a “remote resource” with it’s own unique numeric key, and you want to use one line of code instead of 3 or 4 to express the “find or create by” practice.

But what about things that you have a little more control over? When is right to use that method vs. using a callback in your model to ensure you always have what you need?

The strategies

Assume you have a Group model, which has_one Forum model – and that somewhere on your “group view” page you’ll link to that group’s forum. Two strategies to consider…

  • Strategy A – “be prepared”, and create right away. When you create a new Group, immediately create a Forum for it. Possibly do this with a callback in the Group model during group creation. Otherwise, do something with transactions to make sure the Group and Forum creation are atomic.
  • Strategy B – “just in time”, create when needed. Use a find_or_create_by during the action which requests the Forum belonging to the relevant Group, creating it only as-requested. The Forum will exist by the time the view is rendered, if it didn’t at the time the page was requested.

Issues to consider…

The role of the model

Strategy A keeps your “application objects” (those which must exist for data normalization purposes but which a user doesn’t necessarily know about) creation tucked nicely away in the models, where they belong. It’s right next to a validation, so you can be sure you won’t screw anything up, because you’re tests will catch you if you do. Strategy B could do most of the same, but the creation process is being triggered a bit higher up (in the controller action, by virtue of the page request).

“Unused” records

Strategy A doesn’t care about “extra data” in your database. It creates things you might sometime need, at a time where it can be sure you’d earliest need them. Strategy B doesn’t want you to have a bunch of records no one cares about. It creates them when someone wants to use them, and only when someone wants to use them.

Functionality “by side effect”.

Strategy A thinks that it “feels right” being in the model, and avoids the “functionality by side effect” feeling which sometimes comes with find_or_create_by.

Mind your verbs!

Strategy B uses an HTTP GET to create something – which is usually bad and evil. In this case, you could argue that it’s ok because it’s not a “first class” object, it’s just something your Group needs in order to properly present a forum about itself. You could also argue that that’s really silly, and that since you’re using GET, you’ll have a bunch of search engines which crawl your site and generate all your forums for you, and really, if search engines are going to be creating things in your database, why not just create them the first time around anyway?

Room for second chances

What if you screw up somewhere? Strategy B is really forgiving! Even if you have bad data, or your server crashed in the middle of some non-atomic code, or there are solar flares outside or something – you’ll always check if you have a Forum, and you’ll always create one if you don’t. It’s like wearing a bike helmet.

Wrapping up

So, in conclusion, there’s no conclusion. I think that “just in time” creation done with a find_or_create_by vs. “be prepared” creation done with a model callback are both successful solutions to the “how do I build my non-first-class objects?” question – and choosing the approach to take is probably a matter of taste or non-generalizable project requirements.

Thanks to the thoughtbot dev team for assistance in summarizing this topic for this post.

Tagged:

Comments (View)

What’s the deal with Rails’ polymorphic associations?

The latest big ActiveRecord feature to Rails has been polymorphic associations. Not very clear at first, I found out they’re easier to understand with a couple examples.

A common one:

class Person < ActiveRecord::Base
  has_one :address, :as => :addressable
end

class Company < ActiveRecord::Base
  has_one :address, :as => :addressable
end

class Address < ActiveRecord::Base
 belongs_to :addressable, :polymorphic => true
end

This basically allows the address class to belongs_to any model. Which is nice, the alternative would be to say:

class Address < ActiveRecord::Base
  belongs_to :person
  belongs_to :company
end

Then you’d have all these foreign keys in your addresses table but you only would ever have a value for one of them because an address can only belong to a person or a company but not both.

OK that was the basics.

Now the rails docs refer to the as keyword parameter to has_one and has_many as specifying a “polymorphic interface.” What is that?

When I think”polymorphic interface”, I think something along the lines of the << message in Ruby. I can send that message to a bunch of different objects like arrays, strings, IO streams, etc. and they all know what to do when they receive it.

I think << as a kind of interface that all those different classes implement. From a statically typed language standpoint, such as Java, it would be as if we had a nice little hierarchy of classes all implementing a common interface.

Pretending Java allowed operator overloading and << was an operator it might look like this.

public interface Collection {
  Collection <<(Object anObject);
}

And the classes.

public class Array implements Collection {
  public Collection << (Object object) {
    // add object to me
  }
}

public class String implements Collection {
  public Collection << (Object object) {
    // add object to me
  }
}

Where am I going with this? Stay with me here.

Lets rotate the class diagram for the Person, Company, and Address 90 degrees to the left (I dont know how to draw that here but if you write it out on paper you’ll see what I mean) and make Person and Company inherit from Address.

class Address < ActiveRecord::Base
end

class Person < Address
end

class Company < Address
end

Now neither a Person nor a Company are an Address so lets instead use that “polymorphic interface” as our superclass name.

class Addressable < ActiveRecord::Base
end

class Person < Addressable
end

class Company < Addressable
end

That’s better. A Person and a Company are addressable but what happened to the Address class.

class Addressable < ActiveRecord::Base
  has_one :address
end

There we go. Now Person and Company has_one address, they inherit it from Addressable, and no polymorphic associations.

But wait, inheritance? More specifically in the Rails world, “single-table inheritance” (STI) ? Let’s pretend a Person and a Company have very little state in common; what does using (STI) give us? It’s gives us a giant table with a lot of empty columns for the Company attributes when the row is a Person and a lot of empty columns for the Person attributes when the row is a Company.

I don’t like it.

As more Addressable’s come into the system that table is going to get bigger and bigger. To me using Addressable makes sense, inheritance is about behavior and not about state and if I was modeling without thinking about a database I probably would of first came up with using the Addressable class.

What can we conclude? We can say that STI is basically a way to map an inheritance inhierarchy for a bunch of classes that have a lot of common state not behavior.

Now there are other ways to map an inheritance hierarchy to a relational database. In fact there’s 3 commonly used ones. Rails only gives us the simplest one STI.

  • Single Table Inheritance (STI) - The whole heirarchy is mapped to a single table with an extra column (“type” in Rails) that holds the class name for that row
  • One Table per Concrete Class - Each concrete class gets its own table, the superclass (like all good superclasses) is abstract and does not get its own table. Any common state in the superclasses is duplicated in each subclass table.
  • One Table per Class - Each class in the heirarchy gets its own table. Subclass tables have foreign keys referencing their corresponding superclass row in the superclass table.

For the 2nd one it won’t work. But that last one “One Table per Class” is interesting.

Back to our Person, Company, and Addressable example.

If we mapped each of those classes to its own table what would or database look like?

addressables (id)
people (id, name, age, height, weight, addressable_id)
companies (id, size, established_date, addressable_id)
addresses (id, street, city, state, addressable_id)

Hmmm. We get to use the nice heirarchy that uses behavior to model inheritance with Addressable as our superclass and we don’t have to put all the subclasses into their own table. So we got rid of that big ugly STI table with all those empty columns. When reading a Person from the database, we’d do a join to Person’s superclass table addressables on addressable_id. And to read a Person’s address we’d do a join to addresses on addressable_id.

So we eliminated polymorphic associations and replaced them with inheritance, assuming rails supported our inheritance mapping scheme of “One Table per Class”, which it doesn’t but lets keep going. And I like our heirarchy, a Person is Addressable, a Company is Addressable it reads nice and logical. One beef. What’s the deal with that addressables table? A table with one column. That’s weird. For now, mark it down as a disadvantage and some ugliness with this method.

But wait. Here comes another feature. Users now want to be able tag people and companies. We could use the Rails plugin acts_as_taggable, which uses polymorphic associations. Let’s not and keep running with this to see where it takes us.

A Taggable class sounds good. But wait. Ruby doesn’t allow multiple inheritance and it doesn’t have the Java/C# equivalent of interfaces. Ruby uses modules instead. OK so we screwed up. We should of modeled Addressable as a module and not a class. I say we didn’t screw up - we modeled that because that’s what the current requirements were; we didnt know tagging was coming. That’s another agile story.

Anyway, let’s try using modules.

module Addressable
end

module Taggable
end

class Person < ActiveRecord::Base
  include Addressable
  include Taggable
end

class Company < ActiveRecord::Base
  include Addressable
  include Taggable
end

There that’s better now Addresses and Companyies are both addressable and taggable.

module Addressable
  has_one :address
end

Wait, we can’t do that in Rails. OK how about this.

module Addressable
  def self.included(klazz)  # klazz is that class object that included this module
    klazz.class_eval do
      has_one :address
    end
  end
end

There now, each class that includes the Addressable module has_one Address. Hold up. What would our database look like?

addresses (id, street, city, state, person_id, company_id)

Oh no, we’re back to where we started. An Address can’t belongs_to a Person and a Company at the same time. We need polymorphic associations.

Wow, that was a trip. What did we learn. At first we started out using polymorphic associations. Then we decided to refactor and try modeling in what i’d call “the more natural way” using inheritance and Addressable and Taggable classes. But we eventually got burnt when a Person and a Company both needed to be Taggable as well. So we used Ruby’s version of interfaces/multiple inheritance by using modules. And that got us right back to where we started

The moral of the story is this because Rails only allows you to map inheritance heirarchies using STI plus Ruby’s lack of “interfaces we can’t model using interface like classes like Addressable” and Taggable. Instead we use polymorphic associations and let them use that “polymorphic interface” for the name of the association:

class Address < ActiveRecord::Base
  # here's where we'll use Addressable
  belongs_to :addressable, :polymorphic => true
end

class Tagging < ActiveRecord::Base
  # here's where we'll use Taggable
  belongs_to :taggable, :polymorphic => true
end

I like modeling using interfaces such as Addressable and Taggable. I really like the following Java classes.

public interface Addressable {
  Address getAddress ();

  void setAddress (Address address);
}

public class Address {
  private String street;
  private String city;
  private State state;
  private Zipcode zipcode;
  private Addressable addressable;    // anyone who implements Addressable

  // various getters and setters, etc.
}

public class Person implements Addressable {
  private Address address;

  public Address getAddress () {
    return address;
  }

  public void setAddress (Address address) {
    this.address = address;
  }
}

public class Company implements Addressable {
  private Address address;

  public Address getAddress () {
    return address;
  }

  public void setAddress (Address address) {
    this.address = address;
  }
}

And for Taggable

public interface Taggable {
  Collection getTaggings ();
}

public class Tagging {
  private Taggable taggable;  // anyone who implements Taggable
  private Tag tag;

  // various getters/setters, etc.
}

public class Person implements Addressable, Taggable {
  // Addressable implementation from above
  private Collection taggings;

  public Collection getTaggings () {
    return taggings;
  }
}

public class Company implements Addressable, Taggable {
  // Addressable implementation from above
  private Collection taggings;

  public Collection getTaggings () {
    return taggings;
  }
}

In Object-relational mapping (ORM) libraries in the Java/.Net world they provide all 3 inheritance mapping schemes whereas in Rails you only get STI.

Were the other 2 inheritance mapping schemes too “enterprise” for Rails? Too complicated for DHH to implement? Nah, Ruby’s lack of interfaces make the other 2 schemes not as powerful as in languages that support interfaces e.g. like in the above example Addressable worked fine, but the minute we introduced Taggable i.e. another “interface” we were done for.

And Rails form of “polymorphic associations” aren’t found in Java/.Net object-relational mapping libraries as well. Of course not, Ruby’s use of modules as a form of multiple inheritance required something unique, “polymorphic associations” are that something. Look at the source for the popular acts_as_taggable plugin. It uses polymorphic associations and it uses modules to include in any shared behavior such as instance and classes methods. This is nice. You call acts_as_taggable in your class definition and you get all this behavior for free.

I’m sorry, but I miss my interfaces. Looking at the above Java code, you might say “yeah but look at that Addressable and Taggable implementation in the Person and Company classes its exactly the same, its not DRY. In Ruby with modules you’d only have to implement that once and just include it into the Person and Company classes”. That’s true but if someone decides to change that module it might break classes that include it - that’s another story something called the “brittle base class”. I also like the fact that its explicit, its duplicated but I can see the code in both the Person and Company classes, no messing around in RAILS_ROOT/vendor/plugins.

Well if you made it through that you’re just as crazy as I am. But I’m scoring this one a point for Java/C#. Ruby usually dominates but being able to use those Java/C# interfaces just seem more natural and better to me. And the fact that Rails’ polymorphic associations are a new thing, there’s definitely a source of confusion around them in the Rails community.