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.

Support multiple errors per attribute in ActiveModel Errors JSON serialization

#5615

The current errors json serialization does not work for mutiple errors on a attribute. It returns duplicate keys for subsequent errors for that attribute. This of course can't work when using the JSON object.

So for example this ActiveModel errors hash

{"name" => ["can't be blank", "is too short"]}

Becomes

{"name":"can't be blank","name":"is too short"]}

The change required is to output an regular ordered hash from as_json call with the error messages as an array value. This will be serialized correctly into JSON

{"name":["can't be blank","is too short"]}

It also brings it into line with how ActiveModel returns messages for an attribute, which is now always as an array. We need to be consistent across the board.

The reason the ActiveModel::Errors subclass does not get serialized correctly is due to the each method override. It doubles up the keys for attributes with multiple errors when iterated over. I tried just calling super in the as_json method, but this doesn't work because the Hash as_json method calls map on self. Thereby causing the same issue again.

Reported by Adam Meehan · September 11th, 2010 @ 11:13 AM

State: resolved
Milestone: 3.0.5
Assigned to: Santiago Pastorino Santiago Pastorino
Importance: Medium

Activity

  1. Adam Meehan
    Adam Meehan
    • Tag changed from activemodel to json encoding as_json, activemodel, errors, patch, serialization

    September 11th, 2010 @ 11:14 AM

  2. Lake
    Lake

    +1 applies cleanly to master and the tests pass.

    I'm running ruby 1.9.2.

    September 16th, 2010 @ 12:22 AM

  3. Thilo Utke
  4. Sebastian Cohnen
  5. Gert Goet
  6. Aditya Sanghi
    Aditya Sanghi
    • State changed from new to open
    • Milestone cleared.
    • Assigned user set to Santiago Pastorino
    • Tag changed from json encoding as_json, activemodel, errors, patch, serialization to json encoding as_json, activemodel, errors, patch, serialization, verified
    • Importance changed from to Medium

    Patch applies! tests look fine and pass.

    November 27th, 2010 @ 06:42 PM

  7. Thilo Utke
    Thilo Utke

    Hi I suggest a slightly different solution that fixes to_hash to return the ordered hash instead of self. So you get the expected behavior when calling to_hash and as_json can rely on to_hash. See patch for details.

    November 28th, 2010 @ 01:43 PM

  8. Aditya Sanghi
    Aditya Sanghi

    @thilo yes your version makes better sense.

    November 29th, 2010 @ 01:35 PM

  9. José Valim
    José Valim

    Applied on master. Can we have a patch for 2-3-stable?

    December 1st, 2010 @ 10:44 AM

  10. Repository
    Repository
    • State changed from open to resolved

    (from [7148b933c4865a5140187d7ed792fd6df9b860a4]) ActiveModel::Errors.to_hash returns plain OrderedHash and used in to_json serialization to properly handle multiple errors per attribute [#5615 Support multiple errors per attribute in ActiveModel Errors JSON serialization state:resolved]

    Signed-off-by: José Valim jose.valim@gmail.com
    https://github.com/rails/rails/commit/7148b933c4865a5140187d7ed792f...

    December 1st, 2010 @ 10:46 AM

  11. Santiago Pastorino