Most Rails apps I’ve worked on have followed the pattern “skinny controllers, fat models.” The controller shouldn’t have know what attributes and joins to make when asking for data from the models; one line methods calls in controller actions are a thing of beauty. Controller specs are simplified and the complexity of business logic and database access can be stuffed into the models. Fatten’ up those models!
But what happens when your models grow too large? It’s common to have one or two models (Users and Groups, anyone?) carry a large burden. Over time, we see Ruby files approaching and surpassing thousands of lines and their associated tables accumulating column excess. Before you know it, it’s time to put your models on a diet. It’s useful to have some patterns in your tool-belt to start trimming the fat.
A good refactoring step is to pull out modules of related behavior. In the User model, for example, we might extract modules for related instance methods, associations and validations for functional scopes like admin access or group memberships. I prefer to namespace the modules under UserExtensions so it’s clear, at least in this case, that these are meant for composition of the User model rather than for sharing code across objects. Now ActiveSupport::Concern makes it super-simple to define both instance and class methods in your module and ensure they’re included properly. (Some good reading on better ruby idioms for mixing in class and instance methods).
One convention is to place the modules in “#{model_name}_extensions” folders in your app/models directory to group the code logically. For example, UserExtensions::Admin would be located at app/models/user_extensions/admin.rb. Breaking out the code in to functional chunks like this is a good first step in downsizing your model files. It also more easily allows methods and associations to be extracted into other classes/tables.
Added: Check out part 2 of this post for thoughts on slimming down our models at runtime.

Ross,
I like your example, however I find that using modules makes the models source code “thinner” but they are still “fat” during runtime. Lately I find myself experimenting with value objects, specifications, and collection extensions to fan out responsibilities to other objects. I am also a big fan of creating multiple types of objects say “Admin::User” vs “Subscription::User” and compose them or extend “::User” because generally speaking these two different roles are in very different contexts.
This may seem strange at first but we do it all of the time on the controller level e.g. “Admin::UsersController” vs “Subscription::UserControllers”, so why not apply the same thinking to models?
True, my example is more of a refactoring step doesn’t actually create lighter objects. The next steps for this article should focus on the improving the runtime weight of our model objects. Drawing on your example, I may take a look at how we could use this approach to narrow the set of model attributes selected from the database.