Upgrade codebase to support latest AMS version.

This commit is contained in:
Darren Cheng 2016-07-12 18:04:36 -07:00
parent 78229c9dea
commit 35abadd8f7
9 changed files with 72 additions and 26 deletions

View file

@ -2,7 +2,7 @@
### 1.5.0 (Next)
* Your contribution here.
* [#54](https://github.com/ruby-grape/grape-active_model_serializers/pull/54): Adding support for ASM v0.10. Drops support for ASM v0.9 - [@drn](https://github.com/drn).
### 1.4.0 (July 14, 2016)

View file

@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
gem.licenses = ['MIT']
gem.add_dependency 'grape'
gem.add_dependency 'active_model_serializers', '>= 0.9.0'
gem.add_dependency 'active_model_serializers', '>= 0.10.0'
gem.add_development_dependency 'listen', '~> 3.0.7'
gem.add_development_dependency 'rspec'

View file

@ -3,44 +3,72 @@ module Grape
module ActiveModelSerializers
class << self
def call(resource, env)
serializer = fetch_serializer(resource, env)
options = build_options(resource, env)
serializer = fetch_serializer(resource, options)
if serializer
::ActiveModelSerializers::Adapter.create(serializer).to_json
::ActiveModelSerializers::Adapter.create(
serializer, options
).to_json
else
Grape::Formatter::Json.call resource, env
end
end
def fetch_serializer(resource, env)
def build_options(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, ams_options))
return nil unless serializer
options[:scope] = endpoint unless options.key?(:scope)
# ensure we have an root to fallback on
options[:resource_name] = default_root(endpoint) if resource.respond_to?(:to_ary)
serializer.new(resource, options.merge(other_options(env)))
# ensure we have a root to fallback on
if resource.respond_to?(:to_ary) && !options.key?(:root)
options[:root] = default_root(endpoint)
end
def other_options(env)
options.merge(meta_options(env))
end
def fetch_serializer(resource, options)
# use serializer specified by options
serializer = options[:serializer]
if serializer.nil?
# fetch serializer leverage AMS lookup
serializer = ActiveModel::Serializer.serializer_for(resource)
# if grape version exists, attempt to apply version namespacing
serializer = namespace_serializer(serializer, options[:version])
end
return nil unless serializer
serializer.new(resource, options)
end
def namespace_serializer(serializer, namespace)
"#{namespace.try(:classify)}::#{serializer}".constantize
rescue NameError
serializer
end
def meta_options(env)
options = {}
ams_meta = env['ams_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
options[:meta] = meta if meta
options
end
def build_options_from_endpoint(endpoint)
[endpoint.default_serializer_options || {}, endpoint.namespace_options, endpoint.route_options, endpoint.options, endpoint.options.fetch(:route_options)].reduce(:merge)
[
endpoint.default_serializer_options || {},
endpoint.namespace_options,
endpoint.route_options,
endpoint.options,
endpoint.options.fetch(:route_options)
].reduce(:merge)
end
# array root is the innermost namespace name ('space') if there is one,

View file

@ -5,6 +5,7 @@ describe '#render' do
let(:app) { Class.new(Grape::API) }
before do
ActiveModelSerializers.config.adapter = :json
app.format :json
app.formatter :json, Grape::Formatter::ActiveModelSerializers
end

View file

@ -44,7 +44,10 @@ describe Grape::Formatter::ActiveModelSerializers do
end
end
subject { described_class.fetch_serializer(user, env) }
let(:options) { described_class.build_options(user, env) }
subject { described_class.fetch_serializer(user, options) }
let(:instance_options) { subject.instance_variable_get(:@instance_options) }
it { should be_a UserSerializer }
@ -53,8 +56,8 @@ describe Grape::Formatter::ActiveModelSerializers do
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])
expect(instance_options[:only]).to eq(:only)
expect(instance_options[:except]).to eq(:except)
end
it 'should read serializer options like "root"' do

View file

@ -46,7 +46,10 @@ describe Grape::Formatter::ActiveModelSerializers do
end
end
subject { described_class.fetch_serializer(user, env) }
let(:options) { described_class.build_options(user, env) }
subject { described_class.fetch_serializer(user, options) }
let(:instance_options) { subject.instance_variable_get(:@instance_options) }
it { should be_a V1::UserSerializer }
@ -55,8 +58,8 @@ describe Grape::Formatter::ActiveModelSerializers do
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])
expect(instance_options[:only]).to eq(:only)
expect(instance_options[:except]).to eq(:except)
end
it 'should read serializer options like "root"' do

View file

@ -10,6 +10,7 @@ describe Grape::ActiveModelSerializers do
subject { last_response.body }
before do
ActiveModelSerializers.config.adapter = :json
app.format :json
app.formatter :json, Grape::Formatter::ActiveModelSerializers
end

View file

@ -1,7 +1,12 @@
class BlogPost
include ActiveModel::SerializerSupport
include ActiveModel::Serialization
attr_accessor :title, :body
def self.model_name
to_s
end
def initialize(params = {})
params.each do |k, v|
instance_variable_set("@#{k}", v) unless v.nil?

View file

@ -1,7 +1,12 @@
class User
include ActiveModel::SerializerSupport
include ActiveModel::Serialization
attr_accessor :first_name, :last_name, :password, :email
def self.model_name
to_s
end
def initialize(params = {})
params.each do |k, v|
instance_variable_set("@#{k}", v) unless v.nil?