Sunday, June 23, 2013

ActiveRecord overdose

In the previous post, I highlighted the typical Rails bugs, that I encountered during my research on better ways of working on Rails apps. The bugs were often security-related:

The main common point of the bugs is the ActiveRecord overdose.

ActiveRecord overdose is a surprisingly popular pattern that includes:
  • putting everything into the model class
  • fear of adding new non-AR classes
  • over-relying on convention over configuration
When you look at a typical Rails model, it's a mix of the following responsibilities:
  • persistence 
  • business logic 
  • adapters 
  • view object 
  • form object 
  • others 

The Rails-way ActiveRecord is an enhanced version of the original Active Record pattern. The original pattern assumed only persistence and some simple business logic. The Rails version extended it with the view/form responsibilities. In many cases it's also extended with the adapters.
  • persistence 
    • associations 
    • queries - scopes 
    • saves 
    • simple validations 
  • business logic 
    • state-machine 
    • calculations 
    • tracking changes (touch) 
    • complex validations 
    • some callbacks 
    • feed/timeline/activity 
    • factories methods (class methods) 
  • adapters 
    • service (coordinating multiple adapters) 
    • search 
    • external api 
    • facebook 
    • twitter 
    • exception tracker 
    • metrics tracker 
    • image storage 
    • pdf 
    • mailer 
    • notification 
  • view object 
    • first_name + last_name 
    • foo.to_s 
    • image_path 
    • http boundary details (urls) 
    • i18n 
  • form object 
    • accepts_nested_attributes_for 
    • sanitizing 
    • attr_accessor 
  • others 
    • acts_as_foo (persistence, logic, validations) 
    • concerns 
    • includes 

The core responsibility of an ActiveRecord model is being a representation of a db record. That means handling the persistence and having the basic logic. This usually works great in typical CRUD apps. Once things get more complex, it's time to reconsider the active record pattern. 

The best way of escaping from the ActiveRecord overdose is to do it step by step. I'll focus on that in my later posts.

3 comments:

seban said...

I think there is one more point in genesis of this overdose. Putting all in one sack is too easy in Rails, at least to specified moment. Active Record class came with so big set of methods that it is too easy to build giant chimera on top of ActiveRecord::Base. I wonder if it was harder to do DB layer in Rails, people will add more classes with single responsibility.

Andrzej Krzywda said...

hi Seban,

It's an interesting point.

Would you say, this is a similar problem to the one described here:

http://c2.com/cgi/wiki?FearOfAddingClasses

?

Maybe Rails makes it hard to create new classes, that's why adding to the same sack seems to be so easy?

Unknown said...

Great article! "Fat model, skinny controller" was the worst practice in rails ever.

Check out this related article: http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/