
Learning from Rails' failures - mattetti
http://merbist.com/2012/02/29/learning-from-rails-failures/
======
bryanlarsen
The article doesn't really offer much in the way of concrete suggestions other
than handwavy stuff like "more documentation" and "it changes too fast" and
"it doesn't change fast enough".

Here's my suggestions:

\- make a breaking change to the gem versioning system to force all library,
framework and gem authors to use versions properly. If you make a breaking
change in your API, you MUST change the major number. Rails made a couple of
breaking changes in the transition from 2.3.5 to 2.3.6, for Pete's sake, and a
huge number of breaking changes in any of their 'minor number' upgrades. Many
gems are even worse. Yes, this is going to cause massive version number
inflation. So what? Chrome increments their major number even faster and with
less reason.

\- If a change to a plugin breaks on an older version of Rails, tell the
authors so they can update their gemspec so that other users of older versions
of Rails don't get the update.

\- Make it easier to contribute to the documentation. It's already pretty
easy, but make it easier. Add an "edit this page" link on every documentation
page that goes to the corresponding "edit this file" in the docrails project
in github.

\- 90% of the "documentation" for Rails can be found randomly scattered across
the internet on blog posts. Of course, these are usually out of date.
"Encourage" (with a stick, perhaps) people to stop doing this and instead to
add to the documentation. If that's not appropriate, stack overflow or some
other blessed site. Not a random blog post that's never going to get updated
and will probably disappear in a few years.

~~~
techiferous
> make a breaking change to the gem versioning system to force all library,
> framework and gem authors to use versions properly.

I really like the RubyGems rational versioning policy (
<http://docs.rubygems.org/read/chapter/7> ) and wish everyone followed that.

I think it might be harder for gems like Rails that are actually metagems. But
I do agree that it's surprising for a move from 2.3.5 to 2.3.6 to break
backwards compatibility. Have we forgotten Ruby's ideal of the principle of
least surprise?

Perhaps a good compromise between what Rails is currently doing and what it
should be doing is to add a fourth version number. When the fourth version
number changes, you can rest assured that the change is backwards compatible.
(However, there is always the danger that some plugin/engine/gem author
monkey-patched a part of Rails which could make their code break during a
"backwards-compatible" upgrade to Rails.)

~~~
bryanlarsen
I was probably being a little bit too harsh: the 2.3.5 to 2.3.6/2.3.7 changes
were not intentionally breaking, but given that they added a major new feature
(XSS support), it's not surprising. (2.3.6 was completely busted, but 2.3.7
released a day after 2.3.6 still contained breaking API changes for us)

I like the 4th version number idea. Since everybody in the Ruby community
seems to think that it's okay for major breaking changes to occur on a minor
version bump, let's adjust policy to match practice rather than the other way
around. Let's call the first number the "political" number, the second the
"major", the third "minor" and fourth "patch".

~~~
techiferous
> Since everybody in the Ruby community seems to think that it's okay for
> major breaking changes to occur on a minor version bump

I would say this is true for Rails, but I think (or hope!) there is a
consensus (or at least a majority opinion?) among Ruby developers that any gem
version that breaks compatibility should change the major (1st) version
number. Otherwise, the ~> operator used by bundler and RubyGems becomes
meaningless.

All of the gems that I publish strictly follow the rule that any change that
could break code will bump the 1st version number, any change that adds
features/behavior will bump the 2nd version number, and any change that has no
interface effect (bug fixes, performance enhancements, documentation tweaks)
will bump the 3rd version number.

~~~
bryanlarsen
I hope you're right.

But luckily ~> isn't completely broken. In my rails apps I use ~> x.y.z to
ensure that I only pull in patch level changes.

------
mapgrep
The nice thing about negative posts like this — or, somewhat negative, in this
case — is that they validate the bottled up frustrations of developers who
thought the same thing.

For example, I always wondered if I was crazy to be frustrated that Rails
gratuitously changed the method for grabbing all records from .find_all to
.find(:all) to .all. In other words, they went from having a full method to
having a param to a broader method and then BACK to having a full method. And
along the way they disabled the old methods, without even providing stubs
(e.g. a find_all that called find(:all), until at least one full version had
passed).

There also seemed to be flip flopping on Rails engines. Engine support was
built in to early versions of Rails, and an actively community sprung up. Then
at one point DHH was actively discouraging them, saying they were a mistake,
to the point where the author of one engine I relied on (login engine) just
abandoned it and stopped updating it for new versions of Rails so I had to
write a bunch of login code to migrate to some version of Rails (2 maybe?).
("This is a sideshow project" --DHH
[http://weblog.rubyonrails.org/2005/11/11/why-engines-and-
com...](http://weblog.rubyonrails.org/2005/11/11/why-engines-and-components-
are-not-evil-but-distracting) ) Now engines seem to be back again - the
documentation states "Since Rails 3.0, every Rails::Application is just an
engine" <http://edgeapi.rubyonrails.org/classes/Rails/Engine.html> So engines
went from a "distracting... sideshow" to the core of rails apps. Hmm.

It's somewhat validating to read I'm not the only one frustrated at the common
and sometimes publicly reverted changes in rails.

~~~
petercooper
_In other words, they went from having a full method to having a param to a
broader method and then BACK to having a full method._

You may know this but I wanted to note that this was not a "revert" as such in
case less informed third parties thought this was capricious API design at its
worst.

Today's #all is rather different to yesterday's #find_all in that the former
supports chaining and is lazy evaluated, whereas the latter used to
immediately hit the DB and required criteria to be included all in the one
call.

~~~
mapgrep
Interesting. Do you know (honest question) why they didn't just make
find(:all) work that way? In my imagined perfect world they'd have never got
rid of find_all in the first place, and they'd have just added the lazy eval
to it later. Or, failing that, done similar with find(:all).

Enjoy your podcast.

~~~
petercooper
As I'm not on the Rails core team and didn't really pay much attention to
their design process, all I can offer is the _major_ rewrite of ActiveRecord
from 2 to 3 and, specifically, the introduction of Arel in AR3 had huge
implications for the API design.

Specifically, check out the README at <https://github.com/rails/arel> .. if
you're familiar with Rails 2 and earlier, the sorts of things you'll see there
probably seem quite alien to you. I believe AR had to change a lot to fit in
with this approach to SQL generation.

(And thanks!)

------
eduardordm
I learned from my own mistakes, not Rails per se. (not really, I knew I was
doing it wrong the whole time)

I built a bank/credit card company using Rails (back in 2005/2006). I didn't
know much about Ruby or Rails by then, I was in a hurry (startup hurry). No
one close to me was using Rails, so I was pretty much on my own. God, did I do
Rails wrong. We managed to fix some things by 2008 but the mess came back and
we now are stuck with this:

~ 4k models, 5k controllers, 7k views: Ruby 1.8.7 and Rails 2.3 stuck.

It is our fault that we got to the point where technical debt is making us
build from scratch a new app while the existing one is perfectly functional.
There are so many common design problems in our app that we are lucky it works
so well.

We are almost finishing a new app in rails 3, we are having some trouble, but
it's not the same I hear people complaining about:

\- Our routes.rb is hitting 2mb, reminds me of my old struts.xml

\- I do love REST, but it bites. specially large, complex applications.

\- Testing times :(

\- I need a EJB3 replacement, not activeresource. I need a way to share remote
models to many other rails apps in a NON-RESTFULL way.

\- My peers love url helper methods, I don't.

\- i18n could be improved: currency

I had similar problems with Spring, Seam and JSF. So...

~~~
Vitaly
You can write Java in any language ;)

I've been talking with guys from a big 3 letter company here and they started
using Rails by moving their Java devs to do that. They ended up with 200K
models, mostly generated by some scripts and stuff. some people just miss the
point ;)

~~~
brunomiranda
You're doing it wrong :)

------
VeejayRampay
Interesting article but one thing is bothering me: Rails 3 being far from
offering the same perf than Merb can offer.

Isn't that essentially comparing apples to oranges? People seem to think that
Rails being "slow" is just the symptom of a bad code base and awful design
choices by the developer team. Why not put more emphasis on the fact that the
two frameworks cater to different people, make different assumptions and
decisions in terms of design?

That aside, there's one point where that article really shines: paying hommage
to the wonderful Aaron "@tenderlove" Patterson for investing loads of time on
the innards of Rails to try and hunt performance issues, squash bugs and
question the framework's architecture every step of the way.

This is especially important I think because it goes to prove that "fixers"
still exist. In a programming world where everyone would rather roll out his
own code base then try to fix, patch or contribute to existing and established
projects and frameworks, it's very comforting cause that's obviously when the
community as a whole yields the best immediate results.

~~~
bryanlarsen
Yes, the @tenderlove callout was very nice. It's a thankless job that attracts
criticism, like samgranieri's just below. Samgranieri's criticism is quite
likely valid, but it's so often the lack of offsetting pats on the back that
make such jobs discouraging.

~~~
samgranieri
I'm not criticizing the work that @tenderlove did on journey, I'm just curious
why he replaced josh peek's router. The reader on journey's homepage says the
reasons are too complex, which piqued my curiosity. @tenderlove is doing a
hell of a job on rails (and ruby itself) and I'm glad he's helping out

------
bryanlarsen
Rails does upgrades better than any other fast-moving large open source
project I've seen. They have things like the rails_upgrade plugin, which most
projects don't offer.

Projects that do upgrades better than Rails do so because they either move a
lot slower or they have a lot smaller API area or they don't have a kajillion
plugins available, many of which aren't actively maintained yet are still
useful.

------
bstar77
Reading that Rails is an "older project" kind of took me by surprise. I guess
in internet years, it's about middle age now.

My personal feeling is that Rails still does way more right than it does
wrong. I find that I'm gravitating to the Node frameworks that are modeled
after Rails (tower.js & railway) because working with straight up Express.js
or even sinatra for non-trivial apps is kind of tedious.

------
samgranieri
I've been using rails since 2005. Here are my random observations:

I've never been a merb user, so I cant speak for how much I miss merb. Sinatra
seems to take the place of merb. I do like the result of the merge, rails 3.
Yehuda Katz did a hell of a job making rails easier to understand and modify
under the hood (with railties, engines, stuff like that). Bundler works a lot
better than config.gem. Adding in rack was huge. I'm still not a huge fan of
the sprockets asset pipeline. Jammit could be a better solution. I dont
understand why @tenderlove replaced josh peek's router and replaced it with
journey. Rails generators for coffeescript should generate tests just like the
ruby files do. Something like phantomjs seems to do the trick.

------
johnernaut
Relating stability and non-breaking facilities with WordPress is an extremely
poor comparison, in my opinion.

~~~
mattetti
I agree that it isn't the best comparison but I wanted to give an example of a
product making upgrades/migration really easy.

------
bsodmike
Here's my take on this: [http://www.mwdesilva.com/posts/40-pondering-learning-
from-ra...](http://www.mwdesilva.com/posts/40-pondering-learning-from-rails-
failures)

------
AstonJ
Hi Matt, you make some interesting points. Here's what I think as a relative
newcomer to both Ruby and Rails (but not to building large/busy websites).

MIGRATION/UPGRADES & STABILITY VS PLAYGROUND ZONE. I appreciate what you're
saying and yes upgrading could be easier - but the benefit of the way Rails
does it now, is that uptake is significantly higher, because it is practically
pushed on you. I think I prefer this because it helps keep Rails cutting edge
(one of the reasons I choose Rails over other frameworks). Maybe I'll change
my mind once I've got a few apps that need upgrading - then again maybe not,
I've always preferred redoing things from scratch than upgrading/patching
things anyway (with app-powered sites such as wordpress/vbulletin - I would
redo the customisations from scratch for every major upgrade - but happy to
patch minor updates).

PUBLIC/PRIVATE/PLUGIN APIS. I don't really have an opinion on this.

RAILS/MERB MERGE WAS A MISTAKE. I remember when I first started researching
web frameworks, the Merb and Rails split worried me - as I thought it would
end up in two factions (two frameworks basically aiming for the same thing)
and would split the community. So the merge did two things (for me anyway)
showed me the community is united (and not affected by egos), and made me feel
better about coming to Ruby (instead of going with a framework in another
language).

TECHNICAL DEBTS. Again I don't really have an opinion on this being a relative
newcomer - but I guess many people would disagree.

KEEP THE COST OF ENTRY LEVEL LOW. This one I think I am qualified to comment
on :D I didn't choose Rails because it was 'easy' to get into (although it is,
because it is written in Ruby). I choose Rails because it was the best web
framework. If people want wordpress-ease, they should use wordpress - a web
framework is completely different to an off-the-shelf app which is designed
for one main purpose, even if with some leeway for customisation. I left off-
the-shelf packages for Rails because I hated being restricted by them, and I
was prepared to learn to program to use Rails. To my surprise, learning Ruby
and Rails was _much_ easier than learning say PHP and CakePHP (which I tried
briefly). Also, I believe anyone serious about learning Ruby and Rails, can
easily, in about 3 to 4 months by following this guide:
<http://astonj.com/tech/best-way-to-learn-ruby-rails/>

DOCUMENTATION I have to disagree - I _love_ the Rails Guides, I've been
reading them from start to finish on my Kindle (currently half way through
Digging Deeper). Of course maybe like almost anything they could be better,
but I disagree that they're "far from great". Try working with a forum app
where documentation is next to non-existent lol.

SUMMARY. I came to Rails because I wanted a cutting edge web framework, one
that was written in a clean, modern language - and that's what will keep me
here. I'm aware and happy to continue learning and keeping myself up to date
to stay current. What I don't want is a framework to lag behind others - that
would very quickly make me think about jumping ship... and I reckon a large
majority of others think the same too.

