Skip to content

Commit dff607d

Browse files
committed
Merge pull request #1336 from johnhamelink/master
Grape formatter feature requested in #1258 - Rebased and Repushed (#1273)
2 parents 1301b52 + d85a17b commit dff607d

File tree

8 files changed

+156
-1
lines changed

8 files changed

+156
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Breaking changes:
1616

1717
Features:
1818

19+
- [#1336](https://github.com/rails-api/active_model_serializers/pull/1336) Added support for Grape >= 0.13, < 1.0
1920
- [#1291](https://github.com/rails-api/active_model_serializers/pull/1291) Add logging (@maurogeorge)
2021
- [#1225](https://github.com/rails-api/active_model_serializers/pull/1225) Better serializer lookup, use nested serializer when it exists (@beauby)
2122
- [#1172](https://github.com/rails-api/active_model_serializers/pull/1172) Better serializer registration, get more than just the first module (@bf4)

active_model_serializers.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ Gem::Specification.new do |spec|
5353
spec.add_development_dependency 'bundler', '~> 1.6'
5454
spec.add_development_dependency 'timecop', '~> 0.7'
5555
spec.add_development_dependency 'minitest-reporters'
56+
spec.add_development_dependency 'grape', ['>= 0.13', '< 1.0']
5657
end

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ This is the documentation of AMS, it's focused on the **0.10.x version.**
2323
|----|-----|----
2424
| Ember.js | 0.9.x | [active-model-adapter](https://github.com/ember-data/active-model-adapter)
2525
| Ember.js | 0.10.x + | [docs/integrations/ember-and-json-api.md](integrations/ember-and-json-api.md)
26-
| Grape | 0.10.x + | [#1258](https://github.com/rails-api/active_model_serializers/issues/1258) |
26+
| Grape | 0.10.x + | [docs/integrations/grape.md](integrations/grape.md) |
2727
| Grape | 0.9.x | https://github.com/jrhe/grape-active_model_serializers/ |
2828
| Sinatra | 0.9.x | https://github.com/SauloSilva/sinatra-active-model-serializers/
2929

docs/integrations/grape.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Integration with Grape
2+
3+
[Grape](https://github.com/ruby-grape/grape) is an opinionated micro-framework for creating REST-like APIs in ruby.
4+
5+
ActiveModelSerializers currently supports Grape >= 0.13, < 1.0
6+
7+
To add [Grape](https://github.com/ruby-grape/grape) support, enable the formatter and helper functions by including `Grape::ActiveModelSerializers` in your base endpoint. For example:
8+
9+
```ruby
10+
module Example
11+
class Dummy < Grape::API
12+
require 'grape/active_model_serializers'
13+
include Grape::ActiveModelSerializers
14+
mount Example::V1::Base
15+
end
16+
end
17+
```
18+
19+
Aside from this, [configuration](../general/configuration_options.md) of ActiveModelSerializers is exactly the same.

lib/grape/active_model_serializers.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# To add Grape support, require 'grape/active_model_serializers' in the base of your Grape endpoints
2+
# Then add 'include Grape::ActiveModelSerializers' to enable the formatter and helpers
3+
require 'active_model_serializers'
4+
require 'grape/formatters/active_model_serializers'
5+
require 'grape/helpers/active_model_serializers'
6+
7+
module Grape::ActiveModelSerializers
8+
extend ActiveSupport::Concern
9+
10+
included do
11+
formatter :json, Grape::Formatters::ActiveModelSerializers
12+
helpers Grape::Helpers::ActiveModelSerializers
13+
end
14+
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# A Grape response formatter that can be used as 'formatter :json, Grape::Formatters::ActiveModelSerializers'
2+
#
3+
# Serializer options can be passed as a hash from your Grape endpoint using env[:active_model_serializer_options],
4+
# or better yet user the render helper in Grape::Helpers::ActiveModelSerializers
5+
module Grape
6+
module Formatters
7+
module ActiveModelSerializers
8+
def self.call(resource, env)
9+
serializer_options = {}
10+
serializer_options.merge!(env[:active_model_serializer_options]) if env[:active_model_serializer_options]
11+
ActiveModel::SerializableResource.new(resource, serializer_options).to_json
12+
end
13+
end
14+
end
15+
end
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Helpers can be included in your Grape endpoint as: helpers Grape::Helpers::ActiveModelSerializers
2+
module Grape
3+
module Helpers
4+
module ActiveModelSerializers
5+
# A convenience method for passing ActiveModelSerializers serializer options
6+
#
7+
# Example: To include relationships in the response: render(post, include: ['comments'])
8+
#
9+
# Example: To include pagination meta data: render(posts, meta: { page: posts.page, total_pages: posts.total_pages })
10+
def render(resource, active_model_serializer_options = {})
11+
env[:active_model_serializer_options] = active_model_serializer_options
12+
resource
13+
end
14+
end
15+
end
16+
end

test/grape_test.rb

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
require 'test_helper'
2+
require 'grape'
3+
require 'grape/active_model_serializers'
4+
5+
class ActiveModelSerializers::GrapeTest < Minitest::Test
6+
include Rack::Test::Methods
7+
8+
class GrapeTest < Grape::API
9+
format :json
10+
include Grape::ActiveModelSerializers
11+
12+
resources :grape do
13+
get '/render' do
14+
render ARModels::Post.new(title: 'Dummy Title', body: 'Lorem Ipsum')
15+
end
16+
17+
get '/render_with_json_api' do
18+
post = ARModels::Post.new(title: 'Dummy Title', body: 'Lorem Ipsum')
19+
render post, meta: { page: 1, total_pages: 2 }, adapter: :json_api
20+
end
21+
22+
get '/render_array_with_json_api' do
23+
post = ARModels::Post.create(title: 'Dummy Title', body: 'Lorem Ipsum')
24+
post.dup.save
25+
render ARModels::Post.all, adapter: :json_api
26+
end
27+
end
28+
end
29+
30+
def app
31+
GrapeTest.new
32+
end
33+
34+
def test_formatter_returns_json
35+
get '/grape/render'
36+
37+
post = ARModels::Post.new(title: 'Dummy Title', body: 'Lorem Ipsum')
38+
serializable_resource = serializable(post)
39+
40+
assert last_response.ok?
41+
assert_equal serializable_resource.to_json, last_response.body
42+
end
43+
44+
def test_render_helper_passes_through_options_correctly
45+
get '/grape/render_with_json_api'
46+
47+
post = ARModels::Post.new(title: 'Dummy Title', body: 'Lorem Ipsum')
48+
serializable_resource = serializable(post, serializer: ARModels::PostSerializer, adapter: :json_api, meta: { page: 1, total_pages: 2 })
49+
50+
assert last_response.ok?
51+
assert_equal serializable_resource.to_json, last_response.body
52+
end
53+
54+
def test_formatter_handles_arrays
55+
get '/grape/render_array_with_json_api'
56+
57+
expected = {
58+
'data' => [
59+
{
60+
id: '1',
61+
type: 'ar_models_posts',
62+
attributes: {
63+
title: 'Dummy Title',
64+
body: 'Lorem Ipsum'
65+
},
66+
relationships: {
67+
comments: { data: [] },
68+
author: { data: nil }
69+
}
70+
},
71+
{
72+
id: '2',
73+
type: 'ar_models_posts',
74+
attributes: {
75+
title: 'Dummy Title',
76+
body: 'Lorem Ipsum'
77+
},
78+
relationships: {
79+
comments: { data: [] },
80+
author: { data: nil }
81+
}
82+
}
83+
]
84+
}
85+
86+
assert last_response.ok?
87+
assert_equal expected.to_json, last_response.body
88+
end
89+
end

0 commit comments

Comments
 (0)