Skip to content

Commit

Permalink
Bump version to 1.4.0
Browse files Browse the repository at this point in the history
Adding failing specs for issue #48
Proposition of implementation for #48
Readme update
Travis fix
  • Loading branch information
syntaxTerr0r committed May 9, 2016
1 parent bc758e0 commit cbd95ed
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 4 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ language: ruby
sudo: false

rvm:
- 2.1.1
- 2.3.1
- 2.2.5
- 1.9.3
- rbx-2.2.10
- jruby-19mode
Expand Down
81 changes: 81 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Use [active_model_serializers](https://github.com/rails-api/active_model_seriali
[![Build Status](https://api.travis-ci.org/jrhe/grape-active_model_serializers.png)](http://travis-ci.org/jrhe/grape-active_model_serializers) [![Dependency Status](https://gemnasium.com/jrhe/grape-active_model_serializers.png)](https://gemnasium.com/jrhe/grape-active_model_serializers) [![Code Climate](https://codeclimate.com/github/jrhe/grape-active_model_serializers.png)](https://codeclimate.com/github/jrhe/grape-active_model_serializers)

## Breaking Changes
#### v1.4.0
* *BREAKING* Changes behaviour in serializer namespacing when using Grape API versioning. See [API versioning](https://github.com/jrhe/grape-active_model_serializers#api-versioning)
#### v1.0.0
* *BREAKING* Changes behaviour of root keys when serialising arrays. See [Array roots](https://github.com/jrhe/grape-active_model_serializers#array-roots)

Expand Down Expand Up @@ -78,6 +80,83 @@ end
# root = people
```

### API versioning

If you haven't declared an API version in Grape, nothing change.

If your Grape API is versioned, which means you have declared at least one version in Grape, ie:

```ruby
module CandyBar
class Core < Grape::API
version 'candy_bar', using: :header, vendor: 'acme'

# My shiny endpoints
# ...
end
end

module Chocolate
class Core < Grape::API
version 'chocolate', using: :header, vendor: 'acme'

# My shiny endpoints
# ...
end
end

class API < Grape::API
format :json
formatter :json, Grape::Formatter::ActiveModelSerializers

mount CandyBar::Core
mount Chocolate::Core
end
```

You'll have to namespace your serializers according to each version, ie:

```ruby
module CandyBar
class UserSerializer < ActiveModel::Serializer
attributes :first_name, :last_name, :email
end
end

module Chocolate
class UserSerializer < ActiveModel::Serializer
attributes :first_name, :last_name
end
end
```

Which allow you to keep your serializers easier to maintain and more organized.

```
app
└── api
├── chocolate
└── core.rb
└── candy_bar
└── core.rb
api.rb
└── serializers
├── chocolate
└── user_serializer.rb
└── candy_bar
└── user_serializer.rb
```

or alternatively:

```
└── serializers
├── chocolate_user_serializer.rb
└── candy_bar_user_serializer.rb
```

Thus, ActiveModelSerializer will fetch automatically the right serializer to render.

### Manually specifying serializer options

```ruby
Expand Down Expand Up @@ -185,6 +264,8 @@ Enjoy :)
#### Next
* Adds support for Grape 0.10.x

#### v1.4.0
* Adds support for active model serializer namespace

#### v1.2.1
* Adds support for active model serializer 0.9.x
Expand Down
11 changes: 9 additions & 2 deletions lib/grape-active_model_serializers/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ def call(resource, env)
def fetch_serializer(resource, env)
endpoint = env['api.endpoint']
options = build_options_from_endpoint(endpoint)
ams_options = {}.tap do |ns|
# Extracting declared version from Grape
ns[:namespace] = options[:version].try(:classify) if options.try(:[], :version)
end

serializer = options.fetch(:serializer, ActiveModel::Serializer.serializer_for(resource))
serializer = options.fetch(
:serializer,
ActiveModel::Serializer.serializer_for(resource, ams_options)
)
return nil unless serializer

options[:scope] = endpoint unless options.key?(:scope)
Expand All @@ -28,7 +35,7 @@ def fetch_serializer(resource, env)
def other_options(env)
options = {}
ams_meta = env['ams_meta'] || {}
meta = ams_meta.delete(:meta)
meta = ams_meta.delete(:meta)
meta_key = ams_meta.delete(:meta_key)
options[:meta_key] = meta_key if meta && meta_key
options[meta_key || :meta] = meta if meta
Expand Down
2 changes: 1 addition & 1 deletion lib/grape-active_model_serializers/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Grape
module ActiveModelSerializers
VERSION = '1.3.1'
VERSION = '1.4.0'
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require 'spec_helper'
require 'grape-active_model_serializers/formatter'

describe Grape::Formatter::ActiveModelSerializers do
describe 'with a versioned API' do
subject { Grape::Formatter::ActiveModelSerializers }

describe 'serializer options from namespace' do
let(:app) { Class.new(Grape::API) }

before do
app.format :json
app.formatter :json, Grape::Formatter::ActiveModelSerializers
app.version 'v1', using: :param

app.namespace('space') do |ns|
ns.get('/', root: false, apiver: 'v1') do
{ user: { first_name: 'JR', last_name: 'HE', email: '[email protected]' } }
end
end
end

it 'should read serializer options like "root"' do
expect(described_class.build_options_from_endpoint(app.endpoints.first)).to include :root
end
end

describe '.fetch_serializer' do
let(:user) { User.new(first_name: 'John', email: '[email protected]') }

if Grape::Util.const_defined?('InheritableSetting')
let(:endpoint) { Grape::Endpoint.new(Grape::Util::InheritableSetting.new, path: '/', method: 'foo', version: 'v1', root: false) }
else
let(:endpoint) { Grape::Endpoint.new({}, path: '/', method: 'foo', version: 'v1', root: false) }
end

let(:env) { { 'api.endpoint' => endpoint } }

before do
def endpoint.current_user
@current_user ||= User.new(first_name: 'Current user')
end

def endpoint.default_serializer_options
{ only: :only, except: :except }
end
end

subject { described_class.fetch_serializer(user, env) }

it { should be_a V1::UserSerializer }

it 'should have correct scope set' do
expect(subject.scope.current_user).to eq(endpoint.current_user)
end

it 'should read default serializer options' do
expect(subject.instance_variable_get('@only')).to eq([:only])
expect(subject.instance_variable_get('@except')).to eq([:except])
end

it 'should read serializer options like "root"' do
expect(described_class.build_options_from_endpoint(endpoint).keys).to include :root
end
end
end
end
5 changes: 5 additions & 0 deletions spec/support/serializers/v1/user_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module V1
class UserSerializer < ActiveModel::Serializer
attributes :first_name, :last_name, :email
end
end

0 comments on commit cbd95ed

Please sign in to comment.