I'll take Inheritance over Metaprogramming any day of the week

Andrew Carpenter
02 Oct 2010

Rails applications ship with an ApplicationController from which all controllers inherit; this is a handy way of sharing functionality across all your controllers.

However, as many others have noticed, something parallel does not exist for models. However, you can get the exact same thing by simply creating an ApplicationModel to inherit from, setting abstract_class to true:

  class ApplicationModel < ActiveRecord::Base
    self.abstract_class = true

  class User < ApplicationModel
    validates_presence_of ...

(self.abstract_class = true simply means that ActiveRecord won’t go looking for the application_models database table and that it doesn’t make sense to create an instance of ApplicationModel.)

This provides a number of benefits. First, for shared functionality, you don’t have to use alias_method_chain to hook in to ActiveRecord. This improves code clarity and makes the code more maintainable. Whenever possible, you want to use inheritance instead of metaprogramming.

Secondly, by using inheritance instead of metaprogramming named_scopes just work; ActiveRecord supports model inheritance, but doesn’t necessarily work right when you punch in your functionality. If you were to try to do this without an ApplicationModel, it seems like you could simply add a named_scope into ActiveRecord::Base

Finally, all the shared model code is available in one coherent place, making it easier to see what is going on.