mirror of
https://github.com/samsonjs/grape-active_model_serializers.git
synced 2026-04-27 14:57:43 +00:00
[Issue #13] Add render syntactic sugar
As in issue #13 an example solution provided by @jrhe an implementation of said feature has been created. As per the discussion in the thread this is only a helper to be able to reach the available options provided in the active_model_serializer gem. usage is as follows: ```ruby get '/some_path' do collection = Collection.all render collection, { meta: { current_page: 5 }, meta_key: :pagination_info } end ``` The return value would be: `{ pagination_info: { current_page: 5 }, collection: [item, item] }` If given without a `meta_key` it would return as: `{ meta: { current_page: 5 }, collection: [item, item] }` Any feedback appreciated. @zph, @olleolleolle and @bjoska
This commit is contained in:
parent
3a35a468a5
commit
a7ce076ec7
6 changed files with 198 additions and 4 deletions
10
README.md
10
README.md
|
|
@ -99,6 +99,16 @@ namespace 'foo', :serializer => :bar do
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Custom metadata along with the resources
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# Control any additional metadata using meta and meta_key
|
||||||
|
get "/homes"
|
||||||
|
collection = Home.all
|
||||||
|
render collection, { meta: { page: 5, current_page: 3 }, meta_key: :pagination_info }
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
### current_user
|
### current_user
|
||||||
|
|
||||||
One of the nice features of ActiveModel::Serializers is that it
|
One of the nice features of ActiveModel::Serializers is that it
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,26 @@ module Grape
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_serializer_options; end
|
def render(resources, meta={})
|
||||||
def url_options; end
|
set_meta_and_meta_key(meta)
|
||||||
|
resources
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def default_serializer_options; end
|
||||||
|
|
||||||
|
def url_options; end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_meta_and_meta_key(meta)
|
||||||
|
if meta.has_key?(:meta)
|
||||||
|
Formatter::ActiveModelSerializers.meta = meta[:meta]
|
||||||
|
if meta.has_key?(:meta_key)
|
||||||
|
Formatter::ActiveModelSerializers.meta_key = meta[:meta_key]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
Endpoint.send(:include, EndpointExtension)
|
Endpoint.send(:include, EndpointExtension)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,42 @@ module Grape
|
||||||
# ensure we have an root to fallback on
|
# ensure we have an root to fallback on
|
||||||
endpoint.controller_name = default_root(endpoint)
|
endpoint.controller_name = default_root(endpoint)
|
||||||
end
|
end
|
||||||
::ActiveModel::Serializer.build_json(endpoint, resource, options)
|
|
||||||
|
::ActiveModel::Serializer.build_json(endpoint,
|
||||||
|
resource,
|
||||||
|
options.merge(other_options)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def other_options
|
||||||
|
options = {}
|
||||||
|
if @meta_content_items
|
||||||
|
meta_option = @meta_content_items[:meta]
|
||||||
|
@meta_content_items.delete(:meta)
|
||||||
|
options[:meta] = meta_option if meta_option
|
||||||
|
if @meta_key
|
||||||
|
key_option = @meta_key[:meta_key]
|
||||||
|
@meta_key.delete(:meta_key)
|
||||||
|
options[:meta_key] = key_option if key_option
|
||||||
|
end
|
||||||
|
end
|
||||||
|
options
|
||||||
|
end
|
||||||
|
|
||||||
|
def meta
|
||||||
|
@meta_content_items || {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def meta=(meta_content)
|
||||||
|
@meta_content_items = { meta: meta_content } if meta_content
|
||||||
|
end
|
||||||
|
|
||||||
|
def meta_key
|
||||||
|
@meta_key || {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def meta_key=(key)
|
||||||
|
@meta_key = { meta_key: key } if key
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_options_from_endpoint(endpoint)
|
def build_options_from_endpoint(endpoint)
|
||||||
|
|
|
||||||
65
spec/features/grape-active_model_serializers/render_spec.rb
Normal file
65
spec/features/grape-active_model_serializers/render_spec.rb
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
require 'support/models/user'
|
||||||
|
require 'support/serializers/user_serializer'
|
||||||
|
require 'grape-active_model_serializers'
|
||||||
|
require 'securerandom'
|
||||||
|
|
||||||
|
describe '#render' do
|
||||||
|
let(:app) { Class.new(Grape::API) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
app.format :json
|
||||||
|
app.formatter :json, Grape::Formatter::ActiveModelSerializers
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_resource_with(meta)
|
||||||
|
url = "/#{SecureRandom.hex}"
|
||||||
|
app.get(url) do
|
||||||
|
render User.new(first_name: 'Jeff'), meta
|
||||||
|
end
|
||||||
|
get url
|
||||||
|
JSON.parse last_response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with meta key' do
|
||||||
|
it 'includes meta key and content' do
|
||||||
|
result = get_resource_with({ meta: { total: 2 }})
|
||||||
|
expect(result).to have_key('meta')
|
||||||
|
expect(result.fetch('meta')).to eq({ 'total' => 2 })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with a custom meta_key' do
|
||||||
|
|
||||||
|
it 'includes the custom meta key name' do
|
||||||
|
result = get_resource_with({ meta: { total: 2 }, meta_key: :custom_key_name })
|
||||||
|
expect(result).to have_key('custom_key_name')
|
||||||
|
expect(result.fetch('custom_key_name')).to eq({ 'total' => 2 })
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'ignores a lonely meta_key' do
|
||||||
|
result = get_resource_with({ meta_key: :custom_key_name })
|
||||||
|
expect(result).not_to have_key('meta')
|
||||||
|
expect(result).not_to have_key('custom_key_name')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'junk keys' do
|
||||||
|
|
||||||
|
it 'ignores junk keys' do
|
||||||
|
result = get_resource_with({ junk_key: { total: 2 } })
|
||||||
|
expect(result).not_to have_key('junk_key')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'ignores empty meta_key' do
|
||||||
|
result = get_resource_with({ meta: { total: 2 }, meta_key: nil })
|
||||||
|
expect(result).to have_key('meta')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'ignores empty meta' do
|
||||||
|
result = get_resource_with({ meta: nil })
|
||||||
|
expect(result).not_to have_key('meta')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'Grape::EndpointExtension' do
|
||||||
|
|
||||||
|
subject { Grape::Endpoint.new(nil, {path: '/', method: 'foo'}) }
|
||||||
|
|
||||||
|
let(:serializer) { Grape::Formatter::ActiveModelSerializers }
|
||||||
|
|
||||||
|
let(:user) do
|
||||||
|
Object.new do
|
||||||
|
def name
|
||||||
|
'sven'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:users) { [user, user] }
|
||||||
|
|
||||||
|
describe "#render" do
|
||||||
|
it { should respond_to(:render) }
|
||||||
|
let (:meta_content) { { total: 2 } }
|
||||||
|
let (:meta_full) { { meta: meta_content } }
|
||||||
|
context 'supplying meta' do
|
||||||
|
it 'passes through the Resource and uses given meta settings' do
|
||||||
|
expect(serializer).to receive(:meta=).with(meta_content)
|
||||||
|
expect(subject.render(users, meta_full)).to eq(users)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
context 'supplying meta and key' do
|
||||||
|
let (:meta_key) { { meta_key: :custom_key_name } }
|
||||||
|
it 'passes through the Resource and uses given meta settings' do
|
||||||
|
expect(serializer).to receive(:meta=).with(meta_content)
|
||||||
|
expect(serializer).to receive(:meta_key=).with(meta_key[:meta_key])
|
||||||
|
expect(subject.render(users, meta_full.merge(meta_key))).to eq(users)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
@ -2,5 +2,33 @@ require 'spec_helper'
|
||||||
require 'grape-active_model_serializers/formatter'
|
require 'grape-active_model_serializers/formatter'
|
||||||
|
|
||||||
describe Grape::Formatter::ActiveModelSerializers do
|
describe Grape::Formatter::ActiveModelSerializers do
|
||||||
|
subject { Grape::Formatter::ActiveModelSerializers }
|
||||||
|
it { should respond_to(:meta) }
|
||||||
|
it { should respond_to(:meta=) }
|
||||||
|
it { should respond_to(:meta_key) }
|
||||||
|
it { should respond_to(:meta_key=) }
|
||||||
|
|
||||||
|
context '#meta' do
|
||||||
|
it 'will silently accept falsy input but return empty Hash' do
|
||||||
|
subject.meta = nil
|
||||||
|
expect(subject.meta).to eq({})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'will wrap valid input in the meta: {} wrapper' do
|
||||||
|
subject.meta = { total: 2 }
|
||||||
|
expect(subject.meta).to eq({ meta: { total: 2 } })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#meta_key' do
|
||||||
|
it 'will silently accept falsy input but return empty Hash' do
|
||||||
|
subject.meta_key = nil
|
||||||
|
expect(subject.meta_key).to eq({})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'will wrap valid input in the meta_key: {} wrapper' do
|
||||||
|
subject.meta_key = :custom_key_name
|
||||||
|
expect(subject.meta_key).to eq({ meta_key: :custom_key_name })
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue