Hacker News new | past | comments | ask | show | jobs | submit login
Learning from Rails' failures (merbist.com)
50 points by mattetti on Feb 29, 2012 | hide | past | favorite | 35 comments



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.


> 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.)


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".


> 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.


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.


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... ) 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.


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.


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.


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!)


IIRC "engines" were never built into rails (before 3.0). I believe you were referring to this plugin: https://github.com/lazyatom/engines. Honestly, before rails 3, the whole plugin initialization process was a mess. Things are a lot better now. Props to yehuda katz for great work on refactoring on rails 3.

What's wrong with cutting backwards compatibility with old apis after a while? The core team does provide deprecation warnings when they plan on changing stuff, so it's not a complete surprise.


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...


Good god, that is the fattest rails app (by number of models, views, and controllers) I've ever seen. A 2 MB routes file?!? I'd love to see a gist of that.


- why don't you cut your routes.rb into multiple files ?

- rails doesn't stop you of going off the REST way

- I don't know what ejb3 is, but if you need to share models why not creating an engine ? we have multiple rails engine to share config files, controllers, helpers, models, ... works great; it's just a pain to bundle update everywhere when there's an update in an engine


Wow, i don't think you have framework issue i think you have more of a architecture design issue.

Not sure why you can break you app into smaller parts? compartmentalize your design, that way you solve a lot of problems.


Felt some hate, mostly because I just threw some numbers and did not mention how the app is actually run/built. Really don't know how on earth you can criticize an app you have no idea how it's built (just by numbers!?!?). Show me your code and I will point "common design problems" as well.

I don't agree with the author. If you are really interested in this, I gave a very small talk about our app last year (Railsconf 2011 - Bohconf). If you want to talk about it, just find me at Railsconf 2012. (


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 ;)


You're doing it wrong :)


You are going to find problems in any framework for a program of that size.


Agreed. At this point he needs to start looking at SOA designs and figuring out if he can break this application out into services that can be individually tuned and managed.


mate, you chose the wrong path. no framework is a silver bullet. some are better for specific tasks though. You need to choose carefully. Unfortunately for you, looking at your numbers, you've made about worst choice.

PS I personally would never be a customer of that bank/cc company you described


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.


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.


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


One of the points of the merb-rails merge way to have the best of both. allow for a lean-fast minimal stack just like with mere, but also to allow to have all the bells and whistles of rails if you want to.


And I think it will happen over time, these things just take time. Merb has a clear advantage in terms of modularity and speed that cannot simply be slapped on top of Rails, a more complex and begin-to-end framework. Rails 3.0 marked the first real release with merged code bases, I'm sure the merge wasn't without friction, so hopefully Rails 4 or subsequent releases will go deeper in terms of integration with the philosophy of Merb itself.


It is possible now, but does not seem to be widely adopted. Jose Valim posted an example of a very lightweight app just today - https://gist.github.com/1942658.


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.


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.


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.


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


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



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.


[deleted]


Keep reading the same paragraph: > "I know, I know, you can turn off the asset pipeline and it got better since it was first released. But shouldn't that be the other way around? Shouldn't fun new ideas risking the stability of an app or making migration harder, be off by default and turned on only by people wanting to experiment? "


The features should be turned on for new applications and turned off for upgrades. In fact, that's what the rake rails:upgrade does in some cases. It probably doesn't do that often enough.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: