Hire Us

5 things I would improve in rails

Warning: the content of this article is not considered to be trivial, like “Make ActiveRecord …. just like DataMapper”. These are valuable and realistic improvements that fixes significant problems that I met during 3 years of development with rails.

Multiple select problem

Everyone should know the problem with html checkbox that was fixed pretty good in rails FormHelper#check_box. The same problem appear for multiple select. When you turnoff all options, server don’t receive neither nil nor empty array as the parameter and AR can’t guess that all collection should be deselected. That is not rails fault, but can be solved in rails helpers.
Solution is to add hidden input just like for checkbox. This is how it can be fixed now:

module CustomFormBuilder def select(method, choices, options = {}, html_options = {}) ((html_options[:multiple] ? hidden_field(method, :multiple => true, :value => "") : "") + super(method, choices, options, html_options)).html_safe end end ActionView::Base.default_form_builder = CustomFormBuilder

But this is definitely should be rails behavior.

Mass assignment protection should be more noisy

Mass assignment protection is a good security solution. One thing I don’t understand is why is it a warning but not exception. It can be caused by two reasons:

  • Bug in the source code
  • Attempt to hack something

Both cases are exceptional and dev team should know about them as soon as possible and normal flow should be interrupted. I don’t see any use case when I want to see warning instead of exception.

Migrations rollback in production mode

Rails does good work by rollback all structural changes of the last migration when database support ddl transactions. When an issue appear during deployment the source code will be rollback to the previous successfully deployed version, but the database will rollback just the last migration, but not all applied migrations. Migrator should be improved in production environment to rollback all applied migrations instead of just the last one.

Internal validation concept

All validation in rails is frontend oriented: every validation error suppose to be displayed to user. But in real world this is not true. Some validation is considered internal like:

class Comment < AR::Base validates_presence_of :author, :class_name => "User" end

In this case #author is usually set from #current_user in controller. And if that is not done user see the “Author is required” error in form and don’t understand what’s wrong. Moreover developers don’t know about the issue. This problem can be solved at database level with constraint. Some people accept that approach, but some don’t:

  • Database schema is more hard to change than code.
  • Constraints functionality is limited – use case with comment author is covered but there are more complicated ones
  • By doing system validation in database level we split the logic in two places.

So, my proposal is having a bang version of validation methods that will always raise exception on #valid? method call.

Database errors at ruby level

There are lot of various database errors:

  • Invalid syntax
  • Deadlock
  • Constraint failure
  • etc

All of them appear as ActiveRecord::StatementInvalid at ruby level. That is a big deal to differentiate and classify them. I think Rails should offer some classification.


We are planning this not to be just manifest, but submit pull requests soon.