One of the Ruby on Rails apps that I work on has a few models that have lots of stuff in them. The
Company model in this app is 311 lines long. Now, I know that won't break any records – the
User model in Discourse is 906 lines long – but it's long enough to keep you from holding the whole thing in your head at once. As a result, I've changed the way I organize all the attribute logic in my models.
In all the Rails tutorials, you will see models organized something like this:
class Company < ActiveRecord::Base attr_accessible :name, :billing_address_id, :shipping_address_id, :industry_id, :salesperson_id, :price_level_id validates :name, :billing_address, :shipping_address, :industry, :salesperson, :price_level, presence: true validates :name, uniqueness: true belongs_to :billing_address, class: "Address" # And so on end
I think this is just wrong.
All the logic related to a single attribute is spread out across the entire model. If you want to know what the
name attribute is all about, you have to look in three different places, which means it's easy to miss something. You can get away with this when a model is small, but it's simply unworkable as a model grows larger than the height of your screen. Here's how I would rewrite this model:
class Company < ActiveRecord::Base attr_accessible :name validates :name, presence: true, uniqueness: true attr_accessible :status validates :status, presence: true attr_accessible :billing_address_id belongs_to :billing_address, class: "Address" validates :billing_address # And so on end
This is functionally equivalent to the first example, but it's easy to immediately grasp everything there is to know about the
name attribute – because it's all there on those first two lines and nowhere else. The only drawback is that this approach results in even longer model files (since each
validates_presence_of macro gets its own line), but so what?
Do you really want to be reading the scribblings of a madman? Because that's what the first approach is.