rails/rails — pull request #11812 by gaurish (2013-08-08 23:15:12+00:00)
Title: Add tests for ActiveModel::Serializers::JSON#as_json ordering variations

This is related to a [test](https://gist.github.com/gaurish/6189623) which currently fails on JRuby as JRuby's internal tables differ from MRI.

**Issue**:
the order of attributes in json generated from `ActiveModel::Serializers::JSON#as_json` is dependant on MRI in such a way that any other ruby implementation can't pass this test.Because current implementation of `as_json` uses `ActiveModel::Serialization#serializable_hash` which in-turn uses `instance_values` from ActiveSupport to convert @variables of the model into a hash. The ordering of that hash is depending upon in ruby runtime's internal table and this is where the problem is.

To be more clear, here is an oversimplified example that showcases the root case behind the issue. Consider a `Contact` class:
```ruby
class Contact
attr_accessor :name, :age
end

c = Contact.new
c.name = 'foo'
c.age = 71
puts "order is #{c.inspect}"
```
now, lets run this on various Ruby implementations & notice the ordering of @variables.

```sh
#MRI 2.0
> ruby Contact.rb
order is #

#JRuby 1.7.4
> jruby --client Contact.rb
order is #

#rbx-head
> rbx-head@global Contact.rb
order is #
```
As you notice above MRI does `@name`, `@age` whereas JRuby & rbx do exactly opposite. What this means is, as we are using this ordering of @variables to generate the `attributes` hash, the order will vary according to ruby runtime.

Based on the above, I see 3 options

1. Don't rely on internal tables of ruby runtime. Explicitly sort them on some basis e.,g alphabetical order
2. Accept different ruby runtimes will have subtle difference. in which case, lets make this test specific to MRI & add another jruby & rbx. so order of json is still same but only if you use a same runtime.
3. Stop caring about ordering.

I personally think option 2 is good way to go as it allows us to maintain closest to order in which @variable were defined. so this PR implements that.