I should start by saying, that I like Rails on a lot of areas. But we also know, that all technologies and tools have a flip side, which we come to know about only by using it for some time.
Let us jump right in...
1. Domain Modelling
A lot of the domain objects (though, by all means not all) of the domain model will come from representations of relational database tables. In Rails, these need to inherit ActiveRecord::Base, which is definitely polluting the domain model.
But what about behaviour only domain objects? One example is reporting queries and how to model them. Say I need to select some of the attributes of two joined tables Foo and Bar. One way to do it is to add a static finder method on one of them, say Foo (which one can be hard to choose). The finder will then return instances of the class chosen, Foo, but with a "nice" collection of attributes from the two different class types. Rails marks the instance as "readonly", but it really sucks. The model instance simple gets the attributes you select, even though they do not belong on the type. These are incomplete instances and not all domain logic will work on the model instance.
Actually, a lot seems to be hooked up on inheriting ActiveRecord::Base. There is no real is-a relation here between ActiveRecord::Base and the domain object.
2. Transaction Demarcation in Code
I knew this before entering Rails and I have come to hate it. You need to demarcate your transactions yourself in code. It is really not that nice.
This is totally not as easy and clean as with Java. The sole existence (and need of) of a tool like Capistrano says it all. I have previously blogged about Rails deployment compared to Java and I think that post says it all.
4. Tool Support
Aahh, a much debated subject :-) I for one, can and have worked without nice tools, auto-completion and the like. But, I have also come to love what IDEA can do for me, when coding Java. This includes refactoring, auto-completion, documentation popup etc.
Now, this has changed a lot lately with tools like the IDEA Ruby plugin and NetBeans Ruby and Rails support. But still, there are stuff that is next to impossible to do, simply due to the dynamic nature of the Ruby language and the extensive use of these dynamic features in the Rails framework.
What makes NetBeans and IDEA plugins usable for more than syntax highlightning when doing Rails development is the fact, that they are targeting the Rails framework specificly. Not only the Ruby language.
It is not there. It is as simple as that. There are hacks and stuff out there, but in practise, it is missing from the framework.
6. Attributes of ActiveRecord models "Invisible"
Due to the dynamic nature of Rails, the attributes of ActiveRecord models are added dynamically by ActiveRecord, using a lookup of attributes on the database table. At first a nice thing with respect to speed in development. In the long term, I have found it irritating at best. I need to combine a view of a migration that created the table together with the model, to get the full picture. And even then, I am missing migrations that have added or changed the table.
And I am violating the DRY principle, when I am writing stuff like max length on a column and not null constraints in the migrations, but also needs to write the same in validations on the model.
7. Validations outside ActiveRecord
All the nice validations like validates_length_of or validates_uniqueness_of are tied to ActiveRecord. There are solutions out there to reuse this code in other classes, but it seems like a design error from the beginning.
8. Migrations Become a Pain
Talking about migrations. It quickly becomes unfeasible to use migrations to add extra columns or change an existing model. Often, migrations use the model classes to change the data as the schema changes. But, when running all migrations on a clean database, it is done using the latest and greatest version of the model. Not the version of the model when the migration was originally written.
9. Polluted APIs
Rails adds helper methods on various API classes which pollutes the APIs. But I suspect the Ruby APIs themselves to be quite polluted themselves. Try doing a "Date.methods" in the rails console: What the f*** are all those doing on Date? :-) If you could do completion in the IDE, you wouldn't be able to find the tree for the forrest
The Rails framework documentation is spread all over the apidocs, which is not that good with respect to browsing it. I have found some cookbooks, wikis and other stuff, but there is a real lack of a good users manual and/or wiki controlled by some entity that can keep it together and updated.
So What Then?
Despite the above rants, I do like Rails. And I would also recommend it or use it myself, on some specific type of projects. These are the simple, CRUD-like ones with only a small amount of domain logic and complexity.
What I would love to do next time I startup a completely new project, is to base it on Java technologies this time, but choose them for what they have learnt from Rails. One example could be Tapestry5. Another could be Grails with GORM, but that might be too dynamic, hence experiencing the same problems. And then see how productivity is, while still retaining some of the Java goodies, like nice tool support, static checking, refactorings that works, completion, ...