

ActiveRecord (and Rails) Considered Harmful - michaelty
http://blog.steveklabnik.com/posts/2011-12-30-active-record-considered-harmful

======
gerggerg
It's a bummer this article starts out with a quote about Rails providing a bad
OOP learning environment and then talks about the framework itself never
touching on the learning of OOP again.

\--

    
    
        "it's lead Rails developers to build huge, 
        monolithic models that are hard to test, 
        and violate SRP."
    

...Sounds like you need to structure your code better.

    
    
        "Have you ever seen a 200 line long 
        controller method? I have."
    

... What on earth are you talking about? This has nothing to do with rails.
Structure your code better.

    
    
        "The whole idea of logic in templates 
        leads to all kinds of problems."
    

...Then don't put logic in your templates. Use helpers or logic-less
templates.

    
    
        "MVC has served the web well... 
        ...But I think we're reaching its 
        limits"
    

...If the type of web app you want to make isn't best constructed with an mvc
framework, don't use mvc. But honestly, I can't think of anyway to more
blissfully implement a RESTfull webapp than with respond_to and resourceful
routes.

    
    
        "This post is light on examples. 
        I want this to be the starting point 
        of a discussion"
    

...This exact discussion has been raging for years. Your only chance at
gaining ground is through examples.

\--

This brings me to: When is this post from? I feel like it's 5 years old and
I've slightly been had.

~~~
samstokes
I think his thesis is that Rails should _help_ developers avoid those
pitfalls. That's half the point of a framework (as opposed to a _library_ ):
to show you _how_ to structure your code better.

That's actually a big part of the value of Rails: it picks one of the many
ways to structure a web application (MVC with templates and an ORM), provides
code to support that way, and (relevantly) sets conventions for code
structure, directory layout (app/models/, lib/, etc).

It could have left some of those as plugins - like how Sinatra provides only
routing and templating, and if you want MVC or ORM, you have to add them. But
by making them part of the framework, Rails declared "here is one good way to
structure a web app".

By pushing MVC, Rails helped developers avoid the pitfalls of one-page-PHP
apps (mysite.com/index.php?page=news) - big entangled codebases with database
access, HTML generation and business logic all intermixed. ActiveRecord helped
developers avoid SQL injection attacks, repetitive query generation, and
sprawling ORM config files. They made those problems trivial to avoid, and
thus advanced the state of web development.

The OP acknowledges those contributions of Rails and ActiveRecord, but argues
it's time for them to advance again, as there are new problems they need to
tackle.

------
bradleyland
> The real issue is that changing these things would require some really
> serious changes. It'd involve re-architecting large portions of things that
> people classically identify with Rails, and I'm not sure that Rails wants to
> or can do that.

Remember Merb? Remember Rails 2.x -> 3.x? These were not small changes, and
the community negotiated them successfully.

What I'm saying is, don't get discouraged. The fact that we, as a community,
can be openly critical of our tools is the only way to move them forward. Yes,
there are a lot of blind followers who will defend anything Rails, but I've
noticed that the core contributors are far more open minded about discussing
the warts.

This doesn't mean they'll agree with everything you've said though.
Theoretically pure scripting languages are under-represented in the general
community? Why is that? I think the simplest answer is that they're beyond the
grasp of most programmers. Digressing further, it begs the question of "what
problem do you want to solve?" That is ultimately what any discussion will
revolve around. Where will the balance between purity and accessibility land?
Fortunately, I think there's progress being made there.

------
obiefernandez
Overly alarmist headline, although there are some good points of discussion in
there, especially for Rails newbies. The article left a bad taste because it
didn't elaborate on well-known solutions for the problems cited.

For instance, the sole problem mentioned with ActionController is the use of
instance variables to communicate state to the view templates. The popular
decent_exposure gem [1] eliminates this problem by giving you a declarative
way to program to the controller's stated interface. It completely eliminates
the need for using instance variables in your controller code.

[1] <https://github.com/voxdolo/decent_exposure>

~~~
jordinl
why is it a problem anyway?

~~~
obiefernandez
Use of instance variables to communicate state to views is known to lead to
implicit and tight coupling between controller and templates (and become a
nightmare to maintain over time)

DHH disagrees with this point of view because he considers templates to be
methods of the Controller optimized for generating text. Hence use of instance
variables is not a problem.

------
jordinl
"It took me two and a half years to realize that Ruby classes in the models
folder don't have to inherit from ActiveRecord::Base. That is a problem."

Wow! Maybe you're the problem...

"ActionController relies on instance variables to pass information from the
controller to the view. Have you ever seen a 200 line long controller method?
I have."

Well I haven't, I've actually seen it in Django. Nothing forces you to write
200 lines controller methods.

"The whole idea of logic in templates leads to all kinds of problems."

Again, nothing forces to write a lot of logic in the views, you could write
the minimum necessary.

~~~
karmajunkie
If you haven't seen those kinds of controller methods, I'm wondering if you've
worked on any legacy apps recently? I've yet to see an app with a) more than
one or two skilled developers and b) more than a couple of years old that C)
didn't exhibit that problem in at least a couple of spots. I don't think this
is a Rails problem—its a code discipline problem. If you're fortunate enough
to have only worked on solo projects or teams with extraordinary discipline,
then I'm jealous! But its definitely a problem that creeps into most codebases
sooner or later.

------
bretthopper
The only way to stop putting too much logic in your views is to switch a
logic-less templating system. I'm convinced that willpower, coding standards,
code reviews, etc would never be enough to stop it.

Here's a decent implementation of mustache for Rails:
<https://github.com/goodmike/mustache_rails3>

app/views becomes .rb files which act as a sort of presenters.

app/templates is where your actual mustache templates go.

There's a lot of benefits to this and a huge one is being able to reuse
templates on the client-side.

------
cheald
If you're interested in "view models", then check out Draper:

<https://github.com/jcasimir/draper>

It provides exactly that, and it was a huge "a-ha!" for me when I started
using it. Suddenly, things that felt icky to do in a helper (because they were
tightly coupled to a model) or in the model (because they rightly belonged in
a view helper) had a place to live. My templates are nearly fully devoid of
twisting logic now.

Based on my experience, I think that Rails is missing the decorator/view-model
piece, and would benefit from it as a core addition, but one of the great
things about Rails is that it's easily extensible. Drop the gem in your
gemfile, start using decorators, and go home happy.

------
sebastian_e
From the article:

    
    
        "I've written a lot of crappy code, and most of it is due to following Rails 'best practices.'"
    

Funny how the author purposes to be following 'best practices' yet is doing
things such as writing 200-line methods full of if statements, putting logic
in views, etc. It seems the authors woes stem directly from a lack of 'best
practice' knowledge, not only of Rails but also of Ruby itself.

There will never be a framework that can completely stop developers from
shooting themselves in the foot. Education is the key.

(I'll admit this comment could be much more helpful in as much as stating what
the best practices are which would solve or prevent these problems but I would
be repeating ground covered by better teachers than I. The truth is out there,
seek and ye shall find, etc, etc!)

------
martinvanaken
Same here. I think those discussions are useful because, as you, I think Rails
is really nice, but it does hurt my domain driven design optic. I think many
people are searching various way to overcome the ActiveRecord "problem"
(/design decision). I saw a presentation by Corey Haines on this recently, and
it did gave me some food for thought :
<http://blog.8thcolor.com/2011/11/arrrrcamp-fast-rails-tests/>.

I'm currently working on a new Rails project, and I'm delegating more and more
responsibility to model objects that does -not- extends ActiveRecord. Works
for me, for now.

------
bdimcheff
I've had many of the same thoughts about Rails over the years. I think the
view model idea is definitely worth exploring... it would certainly rid models
of a bunch of view-related stuff that doesn't manage to end up in helpers.

One piece of coupling that really bugs me is doing stuff like link_to(@foo)
that will autogenerate a URL based on the class name of the model. To me, this
is way worse than the table names and makes the routes highly coupled with the
underlying class naming structure. Way too much magic...

~~~
tjogin
Uh, "magic" code isn't "magic", it's just code you don't understand. The
obvious solution is to stop writing it off as "magic" and learn to understand
it.

------
zalew
"The differences between Django's idea of 'views' and Rails' idea of 'views'
are interesting here."

Yep. Actually, Django's MVC implementation is commonly called MTV (afaik it's
not an official term) because the 'views' are in fact controllers.

