README.md in active_model_serializers-0.9.0.alpha1 vs README.md in active_model_serializers-0.9.0

- old
+ new

@@ -1,17 +1,10 @@ -[![Build Status](https://api.travis-ci.org/rails-api/active_model_serializers.png)](https://travis-ci.org/rails-api/active_model_serializers) +[![Build Status](https://api.travis-ci.org/rails-api/active_model_serializers.png?branch=0-9-stable)](https://travis-ci.org/rails-api/active_model_serializers) [![Code Climate](https://codeclimate.com/github/rails-api/active_model_serializers.png)](https://codeclimate.com/github/rails-api/active_model_serializers) -[![Coverage Status](https://coveralls.io/repos/rails-api/active_model_serializers/badge.png?branch=master)](https://coveralls.io/r/rails-api/active_model_serializers) # ActiveModel::Serializers -## Master - 0.9.0 - -**master is under development, there are some incompatible changes with the current stable release.** - -If you want to read the stable documentation visit [0.8 README](https://github.com/rails-api/active_model_serializers/blob/0-8-stable/README.md) - ## Purpose `ActiveModel::Serializers` encapsulates the JSON serialization of objects. Objects that respond to read\_attribute\_for\_serialization (including `ActiveModel` and `ActiveRecord` objects) are supported. @@ -65,18 +58,16 @@ $ rails g serializer post ``` ### Support for POROs -Currently `ActiveModel::Serializers` expects objects to implement -read\_attribute\_for\_serialization. That's all you need to do to have -your POROs supported. +The PORO should include ActiveModel::SerializerSupport. That's all you need to +do to have your POROs supported. -# ActiveModel::Serializer +For Rails versions before Rails 4 ActiveModel::Serializers expects objects to +implement `read_attribute_for_serialization`. -All new serializers descend from ActiveModel::Serializer - # render :json In your controllers, when you use `render :json`, Rails will now first search for a serializer for the object and use it if available. @@ -156,10 +147,33 @@ ```ruby render json: @posts, each_serializer: FancyPostSerializer ``` +## Render independently + +By default the setting of serializer is in controller as described above which is the +recommended way. However, there may be cases you need to render the json object elsewhere +say in a helper or a view when controller is only for main object. + +Then you can render the serialized JSON independently. + +```ruby +def current_user_as_json_helper + CurrentUserSerializer.new(current_user).to_json +end +``` + +You can also render an array of objects using ArraySerializer. + +```ruby +def users_array_as_json_helper(users) + ActiveModel::ArraySerializer.new(users, each_serializer: UserSerializer).to_json +end +``` + + ## Disabling the root element You have 4 options to disable the root element, each with a slightly different scope: #### 1. Disable root globally for all, or per class @@ -203,10 +217,27 @@ root: false } end ``` +## Changing the Key Format + +You can specify that serializers use the lower-camel key format at the config, class or instance level. + +```ruby + +ActiveModel::Serializer.setup do |config| + config.key_format = :lower_camel +end + +class BlogLowerCamelSerializer < ActiveModel::Serializer + format_keys :lower_camel +end + +BlogSerializer.new(object, key_format: :lower_camel) +``` + ## Getting the old version If you find that your project is already relying on the old rails to_json change `render :json` to `render json: @your_object.to_json`. @@ -261,11 +292,11 @@ You can also access the `scope` method, which provides an authorization context to your serializer. By default, the context is the current user of your application, but this [can be customized](#customizing-scope). -Serializers provides a method named `filter`, which should return an array +Serializers provide a method named `filter`, which should return an array used to determine what attributes and associations should be included in the output. This is typically used to customize output based on `current_user`. For example: ```ruby class PostSerializer < ActiveModel::Serializer @@ -483,10 +514,37 @@ "comment_ids": [ 1, 2, 3 ] } } ``` +You may also choose to embed the IDs by the association's name underneath an +`embed_key` for the resource. For example, say we want to change `comment_ids` +to `comments` underneath a `links` key: + +```ruby +class PostSerializer < ActiveModel::Serializer + attributes :id, :title, :body + + has_many :comments, embed: ids, embed_namespace: :links +end +``` + +The JSON will look like this: + +```json +{ + "post": { + "id": 1, + "title": "New post", + "body": "A body!", + "links": { + "comments": [ 1, 2, 3 ] + } + } +} +``` + Alternatively, you can choose to embed only the ids or the associated objects per association: ```ruby class PostSerializer < ActiveModel::Serializer attributes :id, :title, :body @@ -550,10 +608,46 @@ { "id": 3, "name": "happy" } ] } ``` +If you would like to namespace association JSON underneath a certain key in +the root document (say, `linked`), you can specify an `embed_in_root_key`: + +```ruby +class PostSerializer < ActiveModel::Serializer + embed: ids, include: true, embed_in_root_key: :linked + + attributes: :id, :title, :body + has_many :comments, :tags +end +``` + +The above would yield the following JSON document: + +```json +{ + "post": { + "id": 1, + "title": "New post", + "body": "A body!", + "comment_ids": [ 1, 2 ] + }, + "linked": { + "comments": [ + { "id": 1, "body": "what a dumb post", "tag_ids": [ 1, 2 ] }, + { "id": 2, "body": "i liked it", "tag_ids": [ 1, 3 ] }, + ], + "tags": [ + { "id": 1, "name": "short" }, + { "id": 2, "name": "whiny" }, + { "id": 3, "name": "happy" } + ] + } +} +``` + When side-loading data, your serializer cannot have the `{ root: false }` option, as this would lead to invalid JSON. If you do not have a root key, the `include` instruction will be ignored You can also specify a different root for the embedded objects than the key @@ -721,9 +815,32 @@ end end ``` The caching interface uses `Rails.cache` under the hood. + +# ApplicationSerializer + +By default, new serializers descend from ActiveModel::Serializer. However, if you wish to share behaviour across your serializers you can create an ApplicationSerializer at ```app/serializers/application_serializer.rb```: + +```ruby +class ApplicationSerializer < ActiveModel::Serializer +end +``` + +Any newly generated serializers will automatically descend from ApplicationSerializer. + +``` +$ rails g serializer post +``` + +now generates: + +```ruby +class PostSerializer < ApplicationSerializer + attributes :id +end +```` # Design and Implementation Guidelines ## Keep it Simple