25

This is not an opening gambit for RoR bashing - honest!

I'm learning Ruby and the Rails framework. Prima facie it appears to be pretty cool, and a wonderful experience compared to PHP. (In fact, it's reminding me of happier days with C# and .NET.)

However, going into this, I have no experience with this framework or language, and I'm curious - what are the current downsides or things you'd wish you'd known when you were beginning?

(Maybe this should be made a community wiki?)

Matty
  • 1,154
  • 3
  • 13
  • 19
  • I tried rails once and stopped when I realized that database-first entity design is not easily possible. – Falcon Aug 29 '11 at 12:46
  • 5
    http://avdi.org/devblog/2011/08/22/your-code-is-my-hell/ is worth reading. I would add that with any dynamically typed language it is extremely important to have 80% or more test coverage, or refactoring will be nearly impossible. – Eric Wilson Aug 29 '11 at 13:11
  • Making your question more specific and balanced (i.e. "Switching from PHP to Ruby on Rails - Pros and Cons) would remove the need to disavow yourself of bashing and the desire for community wiki. – Thomas Langston Aug 29 '11 at 14:13
  • 2
    @Thomas But that's not my question! The pros and cons of PHP are really well known. RoR's pros are quite easy to find. However, RoR's downsides aren't easy to discover as a newcomer and I suspect they would only be discovered with many years of experience. Learning from others' well-earned experience is the objective of this. Many of the CW's I've read are quite specific in their nature. – Matty Aug 29 '11 at 14:27

8 Answers8

32

This is from experience learning, continuing to learn, and writing a relatively simple application in Rails.

1) Learning Curve

Rails is deceptively simple. The tutorials, videos, and books all demonstrate how quick you can get a working (if ugly) application, but these really just scratch the surface. They tend to heavily rely on code generation and "scaffolding" which admittedly is a good tool when learning but quickly outlives its usefulness.

Make no mistake, Rails is hard to master. Once you get past the very basics (more on this later) you will run headlong into a wall if you need to do more than the extremely simplistic "demo app" functionality that you see touted. You can get by with a basic knowledge of Ruby while learning, but you quickly need to pick up Ruby or you'll be left high and dry (and not the good kind of DRY) if you need to go outside the Rails constraints.

Rails is, as I like to call it in a loving way, paint by numbers programming. If you stick 100% to the conventions (i.e. stay within the lines and use the colors you're told to use) you can make decent applications quickly and easily. If and when you have to deviate though, Rails can go from your best friend to your worst enemy.

2) When All You Have Is a Hammer...

Rails does simplistic CRUD applications very well. The problem comes when your app has to do more than just read/write from a database. Now, for the record the last Rails version I used was 2.3.4 so things may have changed since then, but I ran into major issues when business requirements changed so the application had to have a small workflow system built into it, and integrate with a legacy PHP application. The Rails convention of "one form, one model" works fine for trivial apps and data entry applications, but not so much when you need to do processing logic, or have workflows, or anything that isn't the typical "User enters data into a few text fields, hits Submit" type of thing. It can be done, but it's by no means "easy", or rather it wasn't when I last used Rails.

Also, Rails does not like to play well with other applications that aren't using it's preferred methods of data access; if you have to interface with an application that doesn't have a "Web 2.0" style API, you have to work around Rails instead of with it; again I speak from experience here as this is what happened to me.

3) It's New

Finally, Rails is still the "new kid on the block" in many areas. This doesn't matter for personal use or "I think it's cool and want to learn it" type of scenarios, but speaking as someone who would prefer to use Rails at my day job, if you aren't in a location where Rails is widespread, it can be very difficult to find fulltime work as a Rails developer. It's still largely the domain of "hip, new startups" and not a major player in most metropolitan areas. Your mileage may vary in this regard, but I know my area (Tampa) Rails is essentially nonexistent.

4) Fire and Motion

Rails is ever-changing. This is both a good and a bad thing; it's good because the community evolves and embraces new concepts. It's bad because the community evolves and embraces new concepts. It can be very overwhelming for a Rails newbie because typically when you run into an issue, and look around, you'll see either people recommending such-and-such gem to fix it, or saying that way is bad anyways and you shouldn't use it, here's a better way... and you end up having a laundry list of additional tools to learn along with Rails to keep up with the Rails cognoscenti. Things like Git, BDD/RSpec, Cucumber, Haml/Sass, and a cornucopia of other things all float around and get pushed as the "right way to do things" in Rails-land, and speaking from experience you may end up being swamped trying to learn a dozen or more technologies in addition to Rails, because using the standard Rails toolkit feels "wrong".

This is now compounded even more by Rails 3.1 making Sass and CoffeeScript of all things the default, so a total Rails newbie not only has to learn Ruby and Rails but Sass (arguably simple if you know CSS) and CoffeeScript (not crazy difficult but certainly different enough from raw JavaScript) at a bare minimum to get started, plus it can be assumed Git. Even without factoring in RSpec and friends, and the dozen or more gems that you'll typically end up with, that's 4 different things you have to learn before you can seriously begin to write Rails applications. Compare this to a language like C#, or Java, or even PHP where your HTML/CSS/JavaScript/SQL knowledge isn't going to change and you just have to learn the language itself and perhaps the framework nuances.

Wayne Molina
  • 15,644
  • 10
  • 56
  • 87
  • 3
    W.R.T Rails 3.1 Sass & CoffeeScript are defaults that can easily be turned off. In fact "normal" CSS will just work since Rails 3.1 uses the SCSS syntax of SASS. You could use them but you aren't under any compulsion. W.R.T Git I think Linus explains it better why you should really be using a DVCS like Git, regardless of what framework you use. http://www.youtube.com/watch?v=4XpnKHJAok8 – Shreyas Satish Sep 02 '11 at 19:18
  • Oh I agree, just saying that the Rails default is usually hyped a lot so a newbie will feel pressured to use it (I know I felt that way) – Wayne Molina Sep 02 '11 at 19:48
  • 3
    +1 for #4... if you leave Rails for a year, when you come back everybody will be flying around in spaceships and you'll be in your rowboat thinking wtf? Rails 2 syntax felt old before Rails 3 was released. – jimworm Sep 30 '11 at 13:53
  • -1 Good rails bashing post but you don't even suggest an alternative. "Nested forms" is a tough problem and Rails probably solves it better than anyone. – scottschulthess Mar 04 '12 at 19:55
13

Documentation.

While Rails Guides are great learning resource, Rails (and Ruby, generally) library reference is not easy to navigate. Say, you want to learn more about belongs_to method. Although it is used on ActiveRecord::Base subclasses (one's models), it's not documented in ActiveRecord::Base docs, but in a mixin that the class imports. Essentially, you can not see a comprehensive list of all methods that you can use on an object in one place (except when you fire up irb and check the object itself).

With a highly dynamic language as Ruby, it is not straightforward to tell where a method you are using comes from. It can be a problem, especially for learning programmers trying to get a grasp on a new technology stack.

Mladen Jablanović
  • 1,267
  • 7
  • 10
  • This is a killer for me; whenever I need to debug some of our Ruby/Rails code, I always spent way too much time trying to figure out where a given method was defined; and even then, always have to keep the idea in the back of my head that just because I can see the method definition, it may have been redefined elsewhere. – joev Aug 29 '11 at 19:03
9

Ruby on Rails has a significant learning curve. First you have to learn the oddities of the language, then learn the framework, then learn the Rails Way of doing things, then learn about the many commonly used Gems.

However, when you have learned those things, it does come incredibly naturally. In fact other frameworks start to feel like a burden.

Rails is very TDD/BDD-oriented, so if you are not then that's two more things you'll have to learn before you become a competent Rails programmer. You don't have a compiler and IDEs to back you up, so test coverage is very much your fallback.

Many TDD advocates, myself included, would consider this one of the strengths of RoR, as well as its curse. Once you start to write TDD, you find that the security offered by test coverage is better than the security offered by a compiler. Then having to write code JUST to please a compiler becomes burdening.

TDD doesn't feel like an additional task in RoR, it feels like the only way to work.

Rails has one serious performance problem: each request is queued up behind the currently active one, as opposed to threading them as most frameworks do or allowing blocking events to free other requests as the like of Node.js and Twister do. This means you have to code to make response times fast, but that's quite easy to do in most cases.

Rails is also very much designed to handle content systems very well, which in fairness is a lot of the internet. Doing something a little more complicated, such as a web game or an ecommerce system, means learning new gems. You quickly learn that all the gems are out there, but the more obscure the thing you want to do, the harder it will be to find good documentation.

pdr
  • 53,387
  • 14
  • 137
  • 224
  • Re the performance issues - I seem to recall reading that a lot of those had been largely solved with v1.9 of the interpreter, but I could be completely wrong. Are there any ways to overcome this performance limitation? – Matty Aug 29 '11 at 14:19
  • 1
    @Matty: As I added, code to make response times as fast as possible. Anything that can be left to a backend process, do so. But then you should do that with any framework -- it's just easy not to. Also, jRuby is threaded differently, but it does come with its own problems and my answer was long enough already. – pdr Aug 29 '11 at 14:22
7

In my personal experience, the major headache is around compatibility.

When:

  • there are x rails projects deployed,
  • each project uses y gems.
  • while there are n versions of rails,
  • plus m versions of gems installed,
  • with several versions of ruby,
  • on a single Linux box as production machine.
  • the programmer works on another OS X development notebook.

As a freelancer, who does not have the luxury to update/upgrade most of the things, will face a lot of compatibility issues from above variables... while rails, gems, and ruby keep changing/evolving.

ohho
  • 1,292
  • 8
  • 20
  • 7
    Everything you mentioned is fixed by using [RVM](http://rvm.beginrescueend.com/) (or [rbenv](https://github.com/sstephenson/rbenv)) and [Bundler](http://gembundler.com/). You can have specific versions of Ruby and isolated sets of gems for each project then. – Ashley Williams Sep 05 '11 at 21:36
  • This answer is (now) totally irrelevant. RVM to manage Ruby versioning, Bundler to handle gem versioning; [Capistrano](http://capistranorb.com) to handle deployments to the production server and [Figaro](https://github.com/laserlemon/figaro) takes care of application secrets/environment variables. I develop my application on [Cloud9](c9.io) (a web IDE), and my deployment process is literally `bundle exec cap production deploy`. Capistrano takes care of versioning the application on the server. Like any other framework that comes out (e.g. Node.js), *tools are written to solve your problems*. – Chris Cirefice Jan 23 '16 at 18:48
5

Speed definitely is an issue. Ruby's extreme flexibility comes with a significant performance hit.

Scaling horizontally is a non-obvious task, except for technologies specifically designed for that task, which usually trade off simplicity to scale well.
If you can handle 100 times as many requests per machine with technology A than with technology B, using technology A is worth consideration if you have reason to believe that you can serve your data from a single server for a time frame that allows you to add parallelization afterward.
In 2009 stackoverflow was still served from one web server. Of course this is no longer an option. But I suppose it was good they started with a technology, that could scale up to a lot of users on a single instance, before they had to worry about scaling out.

Compared to that, RoR is really slow. The time to handle simple requests is significant and therefore it's a problem to handle many clients (this is all to be seen in relation to faster alternatives).

For the sake of vague orientation, here are some numbers, comparing various other languages suitable for web development to Ruby:

Note that this doesn't mean, that if you use framework X for Java that it will be exactly 200 times faster than RoR. But the speed difference measured in these benchmarks has an important impact on the overall performance of your app.

back2dos
  • 29,980
  • 3
  • 73
  • 114
  • 4
    This answer only talks about "speed" at runtime. Ruby (and Rails) is optimized for development speed. – Nicolai Reuschling Aug 29 '11 at 13:51
  • 5
    This is not a good comparison. The majority of the time spent in a web request is doing I/O from the database. Linking to cpu-intensive benchmarks is misleading. – ryeguy Aug 29 '11 at 13:52
  • I think it's fair to say that Twitter proved much of this a myth. Yes, they felt they had to get off RoR eventually, but you make it sound like if you had more than 20 users posting regularly then you'd have a serious problem. And I'm not entirely convinced it has been more stable since they moved off either. – pdr Aug 29 '11 at 13:54
  • 3
    @pdr: A lot of twitter's problem was they were using ruby for *everything*, even their backend processes which *were* cpu intensive. Areas like that are were statically typed languages shine. They use Scala for that now. I honestly, truly, believe that using RoR is much faster in terms of development time than C# or Java. I would use it for most of the web app, and then use C# or Scala for any cpu intensive background jobs. – ryeguy Aug 29 '11 at 13:57
  • 3
    +1, for valid points. That being said, you can do a lot to optimize Rails applications. Rack lends its self to being a rather extensible system that allows for a lot of flexibility in how everything gets called. Not to mention, Ruby 1.9 is faster, JRuby is faster. I personally am a big fan of JRuby, being able to mix in the power of the JVM is a wonderful win (just be careful of gems which use exceptions for flow control -> huge overhead) – Xorlev Aug 29 '11 at 14:15
  • ryeguy definitely beat me to it. The tests in that link are completely different than the type of loads that would be seen in serving a website. Not saying its faster than any of those but in a large majority of websites it is sufficiently fast. – Rig Aug 29 '11 at 14:40
  • 2
    @Nicolai Reuschling: What value lies in Ruby or RoR being "optimized for development speed"? Can you provide *verifiable*, *quantitative* data how Ruby actually provides higher development speed than alternatives (Lift for example)? Anything else is just a void claim. Also, this question was about RoR *downsides*. High development speed is an advantage and thus out of the scope of this question. Poor runtime performance is within the scope of this question, because it is a downside. – back2dos Aug 29 '11 at 14:46
  • @ryeguy: These are claims, that you have yet to prove. This depends entirely on the nature of the application. Effective architectures use in-memory caching and can greatly cut DB usage. And apart from that, there's a whole problem space beyond what cookie-cutter frameworks such as RoR are capable to solve. Some of those problems are extremely CPU-intense. – back2dos Aug 29 '11 at 14:52
  • @back2dos: Anecdotal, I know, but I work for a company that owns multiple similar companies. Each company retains their own website/team. One of those companies uses RoR, the rest use .NET/Sitecore. If you could see the two operate, you wouldn't doubt the difference in development efficiency. (note: I don't work for any of these teams, nor do I work on RoR; I have no bias) – pdr Aug 29 '11 at 15:08
  • Github is running pretty fast on Ruby On Rails so why would runtime performance be an issue when you start a new project? With proper architecture it's obviously quite possible to have capable websites running on rails. I rather deal with that portion when I have a problem than prematurely optimize. – mhenrixon Aug 29 '11 at 17:10
  • 2
    @pdr: You're comparing some bloated enterprise CMS to an open source web framework. Compare RoR to [Lift](http://liftweb.net/), [Express](http://expressjs.com/), [Merb](http://www.merbivore.com/), [Sinatra](http://www.sinatrarb.com/), [Flow3](http://flow3.typo3.org/), [Symfony](http://www.symfony-project.org/), [django](https://www.djangoproject.com/) or anything else, that is *an alternative*. – back2dos Aug 29 '11 at 18:36
3

Rails has one serious performance problem: each request is queued up behind the currently active one, as opposed to threading them as most frameworks do or allowing blocking events to free other requests as the like of Node.js and Twister do. This means you have to code to make response times fast, but that's quite easy to do in most cases.

I think this is very misguided. You can run Rails in multithreaded mode. When running in multithreaded mode, you should only use IO libraries that release the GIL ( for example, 'mysql2' gem ) else it becomes sort of pointless.

If you are using jRuby, then you can just run a single rails process in multithreaded mode and fully utilize all the available CPU power. However, if you're on MRI ( Ruby 1.8.x or 1.9.x ), you must run multiple processes in order to fully utilize the CPUs, which is the case with node.js too.

  • A clarification question here - is there an easy to way to find which IO libraries release the GIL? – Matty Aug 29 '11 at 15:54
  • I think the best way to figure that out is to benchmark it https://gist.github.com/35d4769d8c8c0dfafc56 – Pratik Naik Aug 29 '11 at 16:08
  • Another example https://github.com/brianmario/mysql2/blob/master/benchmark/active_record_threaded.rb – Pratik Naik Aug 29 '11 at 16:09
  • Good to hear from one of the core devs! This information's not listed in any of the documentation is it? It's a little tedious (although an interesting activity) to start testing libraries to find this out. – Matty Aug 29 '11 at 16:12
3
  • Rails has a lot of niceties that hide complexity from you. (ActiveRecord associations, the whole validation / saving lifecycle, the interpretation of request data based on provided headers) When you're just starting, this is awesome. As you grow, you will find that you begin to fit your app to "the Rails way" of handling things - sometimes this is good, sometimes this is harmless, and sometimes it's actually counter-intuitive to the thing you are trying to do. Not all database tables should be modelled as objects, a validation step may need to happen elsewhere, etc. A lot of Rails programmers eschew not fighting the framework (which usually is wise), but the long term effect of this is...you will carry the habits of Rails with you to places where they are not necessarily called for.

  • The community has a habit of writing software that is billed as "magic" - caching libs that magically work! Evented I/O that magically makes you faster! Magic magic! What usually is the case here is that a very attractive API is provided for a technical solution which is lacking, and you are fooled by the very pretty examples that the thing does what you intend, and only later find that it covers an incomplete solution. The cycle of this is pretty constant, and you learn to roll with it, but you should definitely get familiar with the idea of reading lots and lots of the code you depend on (a good thing!). Rails community magic solutions are not nearly as magic as the README may suggest, I'm saying.

  • Corollary to above: The more you use Rails, the more you should be reading its source. The better you understand the framework internals, the happier you will be long term. Not really Rails specific in this, but I'm just telling you from experience here. Method names sometimes promise something you're not actually getting.

  • Cargo cultism is an issue w/ Rails, but that is probably true w/ all framework / lang communities. It seems more pronounced (to me) in Rails, and as such tends to give a weird generational look to Rails code - as you work on different Rails projects, you will notice certain tendencies that tend to betray the time period in which they were created. As you can guess from that statement, the community tends to move pretty fast in adopting new solutions and deprecating old ones. You should really be on top of your Ruby news, just to understand some of the code that you'll experience on a daily basis.

  • Generally speaking, I think the issue of data concurrency is usually not well addressed by the community - as you grow an app, when you hit the point where you need to shard data, rollback physically remote changes and lock access to data, the solutions become a bit more hand tuned, which makes some of the nice looking Rails things you do get all muddied up w/ the technical necessities of accuracy. Rails doesn't solve every problem you'll have with a web app, I guess I'm saying, and while the creators certainly don't preach that message it's easy to be fooled into thinking that it's implied.

netshade
  • 131
  • 1
2

Depending on how you look at it, the speed with which Rails changes may or may not be a caveat for you. Things change somewhat radically from year to year as more is grokked out of what sucks and needs solutions.

If you're in active development, you'll have your finger on the pulse of this however.

Xorlev
  • 507
  • 3
  • 7