josevalim/active_model_serializers — pull request #125 by arsduo (2012-09-12 15:44:14+00:00)
Title: Allow options in ArraySerializer#as_json

In ActiveModel::Serializers, as in Rails, you can pass options to Serializer#as_json, which is pretty useful -- sometimes you want to expose extra features, like (our current use case) allowing API clients to request only certain keys in their JSON output (for instance, when requesting a lot of records).

Currently, though, this only works for individual serializers. When you're serializing an array of objects (for instance, after retrieving a number of ActiveRecord objects from your datastore), the serializer doesn't pass through options.

This pull request aims to fix that and make array serialization act more consistently to individual serialization. To fix this, I've made the following changes:
* Serializer::ArraySerializer#as_json now explicitly takes a single options argument, rather than *args.
* _Impact_: While this could be a breaking change, all other as_json methods I've seen personally only take one argument, and the args aren't used anywhere in the method anyway.
* Individual array items, if they're AM::Serializers (or ArraySerializers) are serialized with as_json(options). Previously, for reasons I don't know, the serializable_hash method was preferred.
* _Impact_: I _think_ this makes the implementation more consistent with how it would run for a single item, but I don't know why serializable_hash was preferred over as_json, so I may be missing something. The if, elsif, else control flow is a bit uglier, but it preserves the preference for serializable_hash for other objects if available. (serializable_hash doesn't receive the options and hence can't be used for our purposes)
* _Root_: I do explicitly turn off root elements inside the array unless they're explicitly requested. I don't think this should affect any Rails options, as root isn't a rendering option to my knowledge, but it's a possible issue.
* Non-AM::Serializer and non-serializable_hash-able objects are still called with as_json, but now receive the options.
* _Impact_: it's possible this could break implementations of as_json that don't take an option, but those would be methods that don't maintain the same signature as Serializer#as_json, so that seems acceptable.

I've updated the test suite and it passes.

If the goal isn't clear or it would be otherwise valuable, I would be happy to provide code samples to show how this would be useful (and wasn't working).

Thanks for the great gem!

Alex