Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Rails 3RC's ActiveModel#as_json outputs array of message instead of hash of columns and messages

#5254

This change broke a bunch of my JavaScript code to handle validation on the client side (works perfectly fine on Rails 3B4 but not on Rails 3RC)

To replicate this issue:

Declare a model, say "Expense" with "amount" as a required field:

class Expense < ActiveRecord::Base
  validates_numericality_of :amount
end

In the console,

expense = Expense.new
expense.errors.to_json
=>  "[\"Account is not a number\"]"

Basically there's no way that I can get back the column which the error occurs to handle it on the front-end. In Rails 3 beta 4, it used to return this result, and it's the preferred result as well:

expense.errors.as_json  # I tried to_json and it gave me a stack level too deep
=> { :amount => "is not a number }

For me, I have this snippet in the view code to hook up to my custom JavaScript validations:

var expense = <%= raw expense.to_json(:methods => [:errors]) %>;
// handling errors for the expense depends on the columns in expense.expense.errors

I'd get back the errors as a json object and I can iterate thru the columns attributes to handle the errors, however, this is no longer the case with Rails 3RC.

I checked the log and I think this commit broke the expected behavior : 7bd85a8fc2d216a5e2b1 (http://github.com/rails/rails/commit/7bd85a8fc2d216a5e2b1d0380df572...)

Can you please switch this back to how Rails 3b4 handles the serialization of the errors array? If the user wants to have the full error messages, then they can call another methods like expense.to_json(:methods => [:error_messages]) and this would get them the full error messages.

Thanks,

Alex

Reported by Alex Le · July 30th, 2010 @ 07:47 PM

State: resolved
Milestone: 3.0.2
Assigned to: José Valim José Valim
Importance: High

Activity

  1. José Valim
    José Valim
    • Milestone cleared.
    • Importance changed from to High

    Patch with tests please. Thanks!

    July 30th, 2010 @ 07:54 PM

  2. Alex Le
    Alex Le

    Hi José,

    Here's the patch for this issue. Basically now the ActiveModel::Errors#as_json would return the OrderedHash object itself, which will take care of the json serialization itself.

    So far I got the activemodel test suite to pass 100%, but the activerecord test suite failed at 3 places. However I think it's more or less because of my machine lacking the proper language support. The failing tests in the activerecord suite are: test_validate_case_insensitive_uniqueness, test_validate_uniqueness, and test_validate_uniqueness_with_limit_and_utf8, none of which relate to the json serialization.

    This is my first time patching Rails, so if I missed something, please let me know.

    Cheers!

    Alex

    July 30th, 2010 @ 10:04 PM

  3. José Valim
    José Valim

    Congratulations on your first patch! From what I saw, it looks great. I will try to apply it during next week. Thanks!

    July 30th, 2010 @ 10:15 PM

  4. Repository
  5. Adam Meehan
    Adam Meehan

    This issue needs a little more thought. For example if we have multiple errors for an attribute we get a JSON hash with duplicate keys of the attribute name.

    September 11th, 2010 @ 08:31 AM

  6. Adam Meehan
  7. Jeremy Kemper