Ruby on Rails is maybe the most praised web development framework exist. There are tons of reasons for that, but every framework, even the best of its kind, has its drawbacks.
I'd like to know the most common problems you run into when developing Ruby on Rails applications and the issues you often struggle with.
Frequent version updates to the framework make it hard to keep your app up to date - upgrades can break in obscure places.
MonkeyPatching - can cause serious problems for anyone that has to maintain a large codebase over a long period of time.
Performance/Power - Easy to shoot yourself in the foot with memory-consuming database queries using Ruby iterators with ActiveRecord.
But I'll take it over Java or PHP any day
I'm not thrilled about Rails' use of global variables for everything. Model classes find the database connection through a global variable (ActiveRecord::Base.connection), there is the Rails class which is a global access point for things like the logger, the current environment, for caching, etc. ActionMailer makes global variables out of your mailers, and so on and so forth. Rails is built around the use of global variables, so that whatever you do, at any level of the application, you can always reach for a global variable.
This makes testing ugly. If Rails was built on Java, it would make testing really, really hard, but since it's Ruby it just gets ugly. Tests need to stub out a lot of global context in order to run in isolation, and that can easily make tests seem nonsensical. It's not uncommon to see five or ten lines of code that stubs out different global variables, followed by one or two lines of actual test. It's not that five or ten lines of setup for a test is a problem, but without reading the code under test you can't easily see what impact the global state will have, and how it is significant. This makes many tests unnecessarily ugly.
I find it a bit ironic that the Rails community is the most test savvy of any that I've been part of.
Having said that I wouldn't trade Rails for anything that is currently available. The speed at which you can get things done, and the huge number of plugins and gems that removes all the tedious work just blows me away every day.
Like any tech, there's a learning curve. But as a relatively new framework, DHH et al, have been able to "stand on the shoulders of giants" (predecessors) and have produced a great framework.
I've been very happy with choosing Rails as the framework for my commercial sw.
Disadvantages? Not as many libraries as older frameworks such as Java and Perl. -- But there are ways around that problem. Eg call those libraries from Rails or port them.
Performance is usually mentioned in the disadvantages category but cheaper hardware and improvements in later versions of rails have taken care of that. Same with "stability."
For multi-threaded applications, Ruby Threads are called green threads, which are not OS level threads. This can't provide true multi-threading.
Related
I am writing an application where the webapp will be rails and it will allow a user to input rules/ruby-logic and save them to the database. Later on, Java will come along and grab these rules (if/else/elseif) and will execute them via jruby engine. I am wondering of the negatives and possible side-effects of this? And having two languages here?
I want to do rails front-end because the available plugins, and speed of development of webapps. For example, groovy doesnt have as many plugins and i believe that it's much slower in development.
Am I missing anything, or possible logic that may be hurtful in the future if I choose this solution?
In addition I think since ruby is dynamic it will be easier for the user to input rules via a 'ruby' syntax instead of another third-party library like bean shell.
I feel like most complex applications end up needing several languages eventually, usually interfacing through the DB as you're planning. I'm not sure what constraint leads to you Java on backend rather than ruby (guessing legacy or performance), but if that's a requirement then your plan sounds reasonable.
As far as negatives/side-effects, Jruby seems to lag a bit behind the latest ruby, but that's not generally a big deal as long as you match versions for the UI & backend. I can't think of anything that would be harmful in this off the top of my head, but the devil is always in the details ;-)
I'm trying to come up with things that Ruby (or Rails) either doesn't handle well, or things that are way too hard to do in Ruby.
So far I'm having a tough time, but I figured some people on here MUST have know some things that Ruby or Rails don't handle too well.
Anyone?
Ruby is a language. Rails is a framework. Many of the things Rails isn't good at, such as anything not relating to a web framework, Ruby handles with ease.
The other question of what Ruby as a language is not good at is simple. Anything extremely performance intensive is probably better written in C. Ruby won't run natively on most smart phone devices so mobile apps are out. Ruby is not designed for embedded devices, so powering the next space shuttle launch is also a no go. Furthermore the lack of a maternal instinct make Ruby a bad choice to watch young infants.
There is nothing, it's simply perfect. ;-)
Ok, some downsides:
Ruby has questionable parallelism and threading support. See for more details: http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/
Windows support isn't up to par since most Ruby developers simple don't care (like me)
The stuff you'll most commonly hear about scaling issues is a myth. Unless you're making a second twitter perhaps.
There's very little you flat-out couldn't do in Ruby, but there's a few things you wouldn't want to do, mainly involving highly numerical computation. For most of those you could easily write a binding to a C-based API (or some other more performant library.) Image processing, for example, is something that would be dog slow for any non-trivial example in pure Ruby, but you can use RMagick to do it, which is a binding to the much-faster ImageMagick library.
Just about any other use for Ruby is fair game. I've written GUI apps with it, a lot of system services and more one-off scripts than I could count.
Well, it's a framework, so it optimizes for the most common cases. If your app requires unordinary and bizarre things (eg huge performance requirements, needs to use non-Ruby libraries), then Rails might not be suitable.
It seems to me that whenever a company hits these cases (usually performance rather than functionality or integration with other systems) they have to write their own stuff - Google has Big Table, Facebook has their own webserver, etc.
If you're in this position, you're most likely rolling in money and spending some of it to rewrite your code isn't going to be an issue.
However, Rails is great for most normal apps! I don't think it has any gaps that might cause pitfalls in normal cases.
I have some (I think) really great ideas for an online strategy game similar to Travian. There's some content that I haven't yet figured out and some other challenges that I don't know of yet.
This is quite a big project and perhaps too heavy for one person that isn't a skilled web developer (yet). I'd still like to give it a shot, but I'm having trouble choosing a platform. The world "scales" has been thrown around a lot lately and I've seen Ruby on Rails being bashed because it doesn't scale well, so I've come here to get some answers.
I like Ruby on Rails, both Ruby and Rails. I'm certainly no expert at it but I love working with it. I have also worked with Python + Django before and also with PHP (which I am not fond of.)
Ideally the game would have, let's say, 7000 players per server, presumably a lot of data to be processed per second. Would RoR still be a viable platform?
I'm sorry if this question is vague, I guess I'm looking for a "RoR is fine, go at it!" kind of answer. Anything you might want to add is fine.
Thanks!
So if I were you, I would be looking into non-blocking servers like node.js, just because they are MUCH more suited to keeping many connections open for long periods of time, which is what games need to do, compared to traditional web servers.
That being said
There are 3 main things to worry about when you are scaling a web app; memory, execution speed, and io (hd and network) in that order.
For memory, things are much better then they used to be. Phusion Passenger uses copy on write to fork its workers, so the rails environment will get shared among all the workers on a given slice, which is pretty significant. There have also been huge improvements to the way ruby manages memory compared to "the dark times", if you are using 1.8.7 then you want to be using the patches that make up Ruby Enterprise Edition (the difference is like night and day). 1.9.x was pretty much a total rewrite of the runtime, so if you are using that the memory issues ruby had have already been addressed.
For execution speed, 1.8.7 is typically "fast enough" (at least after tuning garbage collection settings). 1.9.2 is actually around the same speed as python, which puts it on the faster side of interpreted languages. How important this point is completely depends on the nature of your application.
Last point is IO, which isn't really a concern of rails, but more your persistence strategy. Rubyists tend to love new things, so you will find first class support for things like redis and mongodb, with loads of people talking about using them and their wins/gotchas. I would look into mongo if I were you and see if the durability trade-offs are acceptable.
I was in java/.net before going to rails, and at the end of the day you are going to pay more for infrastructure, but the amount will be completely dwarfed by what you save in development time.
build it in Rails, host it on Heroku.com - job done. Almost infinite scaling that you don't have to worry about how it works (it just does) and it hosts a lot of highly trafficked Facebook apps so can more than handle it.
I think Ruby on Rails is a good choice for what you need. Actually, we recently created a platform for an online gaming tournament, where players and their gaming bots were playing a logic game.
We used Ruby on Rails and Sidekiq on the backend, ReactJS and WebSocket on the frontend. And it worked well for a quite massive number of players. Here is the tutorial based on what we learnt while building it: How to Write a Game Engine Using Ruby on Rails
As you said yourself, you already have the answer and you are only looking for encouraging words:). I am not RoR expert myself, but I don't think scalability is still such a great issue on this platform. I would advice you to do an architecture spike (XP terminology). Write a test with 7000 clients and method which would perform similar operations to what you intend to create. For example you might load files, render views or even just wait... The point is to test only the thing you are worried about. Good luck!
This is a bit of an impossible question to answer because in order to know whether rails is suitable for what you want to do we would need to a lot more about what you are trying to do. The best advice I can give in the absence of information is for you to check out the railslab scaling videos in order to work it out for yourself.
I'd like to know situations in which I should consider using a framework other than Rails.
Two things. First, Ruby is a relatively young language, and you may run into brick walls when trying to do slightly more esoteric things (like connect to non mainstream or older types of datasources). It also has poor GC, and no kernel threads, both of which are very important for a high performance platform. The main codebase (MRI) is quite hacky (lots of clever obfuscating programmer tricks like macros) and there are parts that are poorly written (gc and thread scheduling leap to mind). Again, it is a very young platform that got very popular very fast.
Secondly, while ruby the language and rails the ideas/paradigm are both phenomenal, ruby and rails the platforms are not. There is a hell of alot in both ruby and rails that is downright ugly, and deployment solutions are in the dark ages compared to what is considered normal for other platforms (php/asp/jsp).
Being accused of trolling here, so I will expound a bit. Due to the threading model, Rails cannot process requests concurrently unless you launch multiple full instances of your rails app. To do that you have two options, the relatively young and still under development passenger (mod_rails), or the tried and tested apache load balancer with multiple mongrel instances behind it.
Either way, the lack of the ability to just just spawn workers means you will want 5-10 full instances of your application running, which incurs a very large overhead (can easily be 300-500megs per app depending on your gems and how big your app is). Because of that, the infrastructure needed to serve rails is a hell of alot more complecated then most other things.
Now, that being said, the situation has been continuously getting better (I mean, passenger is usable now, it wasn't the last time I had to deal with deploying a rails app). I would be very surprised if rails doesn't catch up in the next few years.
Also, rubinius/jruby are doing things the right way, and are moving along at a great pace. I wouldn't be suprised if MRI gets dropped in the next few years in favor of one of those implementations for mainstream rails work.
Ruby on Rails isn't trying to be an end-all be-all web development framework. If you're going to build an application that is predominantly built using CRUD operations, you want to use a lot of AJAX, and you have total control over the database, then Ruby on Rails is one of a few excellent options. If you're doing something else, then there is a probably another framework that is a better match for your requirements.
edit: Matt amended his answer tastefully :) I've removed my own comments pointing out the things he's fixed.
Yes, Ruby definitely has some shortcomings. Green threads being a huge one. But as Matt has said, things are moving along in better directions.
The other posts are pretty much on the money. Decently simple CRUD apps are best suited for rails, though there are other frameworks you can try in Ruby that offer more flexibility.
Here's a great (and might I add objective) example of where not to use rails: Does the Rails ORM limit the ability to perform aggregations?
Wow, way to start a flamewar!
I'm going to start it off by saying that Rails will work for most apps. However, if you need to do a lot of async type work (like messaging between systems, such as getting a request, placing it in a queue and processing it in a different thread, or even on another machine), Rails is probably not your best choice. Ruby, at least at the current time, is not really strong on multithreaded code.
Let the insults fly!
I have a memory of talking to people who have got so far in using Ruby on Rails and then had to abandon it when they have hit limits, or found it was ultimately too rigid. I forget the details but it may have had to do with using more than one database.
So what I'd like is to know is what features/requirements fall outside of Ruby on Rails, or at least requires such contortions that it is better to use another more flexible framework, even though you may have to lose some elegance or write extra boilerplate code.
Rails (not ruby itself) is proud to be "Opinionated Software".
What this means in practice is that the authors of rails have a certain target audience in mind (themselves basically) and aim rails specifically at that. If X feature isn't needed for that target audience, it doesn't get added.
Off the top of my head, things that rails explicitly doesn't support that people may care about:
Foreign keys in databases
Connections to multiple DB's at once
SOAP web services (since rails 2.0)
Connections to multiple database servers at once
That said, it is very easy to extend rails with plugins, and there are plugins which add all of the above functionality to rails, and a lot more, so I wouldn't really count these as limits.
The only other caveat is that rails is built around the idea of creating CRUD web applications using MVC. If you're trying to do something which is NOT a CRUD web app (like twitter, which is actually a messaging system, or if you are insane and want to use a model like ASP.NET webforms) then you will also encounter problems. In this case you're better off not using rails, as you're essentially trying to build a boat out of bicycle parts.
In all likelihood, the problems you will run into that can't just be fixed with a quick plugin or a day or 2 of coding are all inherent problems with the underlying C Ruby runtime (memory leaks, green threads, crap performance, etc).
Ruby on Rails does not support two-phase commits out of the box, which maybe required if your database-backed application needs to guarantee immediate consistency AND you need to use two or more database schemas.
For many web applications, I would venture that this is not a common use-case. One can perfectly well support eventual consistency with two or more databases. Or one could support immediate consistency with one database schema. The former case is a great problem to have if your app has to support a mondo amount of transactions (note the technical term :). The latter case is more typical, and Rails does just fine.
Frankly, I wouldn't worry about limits to using Ruby on Rails (or any framework) until you hit real scalability problems. Build a killer app first, and then worry about scalability.
CLARIFICATION: I'm thinking of things that Rails would have a hard-time supporting because it might require a fundamental shift in its architecture. I'll be generous and include some things that are part of the gem/plugin ecosystem such as foreign key enforcement or SOAP services.
By two-phase commits, I mean attempting to make two commits to physically distinct servers within one transactional context.
Use case #1 for a two-phase commit: you've clustered your database, so that you have 2 or more database servers and your schema is spread across both servers. You may want to commit to both servers, because you want to allow ActiveRecord think do a "foreign key map" that traverses across the different servers.
Use case #2 for a two-phase commit: you're attempting to implement a messaging solution (sorry, I'm J2EE developer by day). The message producer commits to the messaging broker (one server) and to the database (a different server).
Also found some good discussion about the limits of ActiveRecord.
I think there is a greater “meta-question” here, that could be answered and that is “when is it OK to lean on external libraries to speed up development time?”
Third party libraries are often great and can drastically reduce development time, however there is a major problem, Joel Spolsky calls this “the law of leaky abstractions.” If you look that up on Google his post will come up first. Essentially this means that the trade off in development time means that you have no idea what is going on under the covers. So when something breaks you are completely stuck and have very limited methods of debugging. This also means that if you hit one of the features that are simply unsupported in RAILS, that you really need, you’ll have no next step except to write the feature yourself, if you’re lucky. Many libraries can make this difficult to do.
We’ve been burned badly in my dev shop by this issue. Our solutions worked fine under normal load, but we found that the third party subscription libraries that we were using simply could not stand up to the kind of load that we experienced once our site started to get a large number of concurrent users. This puts us in a very difficult place; essentially we have to rewrite the entire subscription service ourselves, with performance in mind. Doing this means that we’ve wasted all the time that we spent using the library.
Third party libraries can be great for small to medium sized applications; they can drastically reduce development time and hide complexities that aren’t necessary to deal with in the early stages of development. However eventually they will catch up with you and you’ll likely have to rewrite or re-engineer your solution to get past the “law of leaky absctractions”
Ruby don't have a functionality like IsPostBack in ASP.Net
Orion's answer is right on. There are few hard limits to AR/Rails: deploying to Windows, AR connectors that aren't frequently used, e.g. Firebird, ), but even the things he mentioned, multiple databases and DB servers, there are gems and plugins that address those for legacy, sharding, and other reasons.
The real limitation is how time-consuming it is to keep on top of all the things that rails devs are working on, and researching specific issues, given how many blogs, and how much mailing list volume there are.