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 – theUser 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 attr_accessible and 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.