From 78229c9deaad6b9564977cfbcf1a214738df45f0 Mon Sep 17 00:00:00 2001 From: Naoki Kobayashi Date: Sun, 26 Jun 2016 00:59:01 +0900 Subject: [PATCH 1/5] Use ActiveModelSerializers::Adapter --- lib/grape-active_model_serializers/formatter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/grape-active_model_serializers/formatter.rb b/lib/grape-active_model_serializers/formatter.rb index 067ced1..1b3514d 100644 --- a/lib/grape-active_model_serializers/formatter.rb +++ b/lib/grape-active_model_serializers/formatter.rb @@ -6,7 +6,7 @@ module Grape serializer = fetch_serializer(resource, env) if serializer - serializer.to_json + ::ActiveModelSerializers::Adapter.create(serializer).to_json else Grape::Formatter::Json.call resource, env end From 35abadd8f7fd24d6d37abf031221c9f4e9005868 Mon Sep 17 00:00:00 2001 From: Darren Cheng Date: Tue, 12 Jul 2016 18:04:36 -0700 Subject: [PATCH 2/5] Upgrade codebase to support latest AMS version. --- CHANGELOG.md | 2 +- grape-active_model_serializers.gemspec | 2 +- .../formatter.rb | 60 ++++++++++++++----- .../render_spec.rb | 1 + .../formatter_spec.rb | 9 ++- .../versioned_api_formatter_spec.rb | 9 ++- spec/old_grape_ams_spec.rb | 1 + spec/support/models/blog_post.rb | 7 ++- spec/support/models/user.rb | 7 ++- 9 files changed, 72 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bc594c..21062e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/grape-active_model_serializers.gemspec b/grape-active_model_serializers.gemspec index 9ec4580..c81cdc9 100644 --- a/grape-active_model_serializers.gemspec +++ b/grape-active_model_serializers.gemspec @@ -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' diff --git a/lib/grape-active_model_serializers/formatter.rb b/lib/grape-active_model_serializers/formatter.rb index 1b3514d..bc97e1b 100644 --- a/lib/grape-active_model_serializers/formatter.rb +++ b/lib/grape-active_model_serializers/formatter.rb @@ -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 + + options.merge(meta_options(env)) end - def other_options(env) + 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, diff --git a/spec/features/grape-active_model_serializers/render_spec.rb b/spec/features/grape-active_model_serializers/render_spec.rb index 0d69f30..e226918 100644 --- a/spec/features/grape-active_model_serializers/render_spec.rb +++ b/spec/features/grape-active_model_serializers/render_spec.rb @@ -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 diff --git a/spec/grape-active_model_serializers/formatter_spec.rb b/spec/grape-active_model_serializers/formatter_spec.rb index 283fec3..1c00125 100644 --- a/spec/grape-active_model_serializers/formatter_spec.rb +++ b/spec/grape-active_model_serializers/formatter_spec.rb @@ -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 diff --git a/spec/grape-active_model_serializers/versioned_api_formatter_spec.rb b/spec/grape-active_model_serializers/versioned_api_formatter_spec.rb index 0586bbc..e4545a1 100644 --- a/spec/grape-active_model_serializers/versioned_api_formatter_spec.rb +++ b/spec/grape-active_model_serializers/versioned_api_formatter_spec.rb @@ -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 diff --git a/spec/old_grape_ams_spec.rb b/spec/old_grape_ams_spec.rb index f4f6384..b71caa4 100644 --- a/spec/old_grape_ams_spec.rb +++ b/spec/old_grape_ams_spec.rb @@ -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 diff --git a/spec/support/models/blog_post.rb b/spec/support/models/blog_post.rb index 4cd580a..0758231 100644 --- a/spec/support/models/blog_post.rb +++ b/spec/support/models/blog_post.rb @@ -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? diff --git a/spec/support/models/user.rb b/spec/support/models/user.rb index 7b84800..62c3560 100644 --- a/spec/support/models/user.rb +++ b/spec/support/models/user.rb @@ -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? From 62faac16c33f4a08a898863a1ff21ba34c2bacde Mon Sep 17 00:00:00 2001 From: Darren Cheng Date: Tue, 12 Jul 2016 22:54:00 -0700 Subject: [PATCH 3/5] Drop Ruby v2.1 support. --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1ed309f..77506f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,6 @@ matrix: env: GRAPE_VERSION=HEAD - rvm: 2.3.0 - rvm: 2.2.5 - - rvm: 2.1 - rvm: rbx-2 - rvm: jruby-19mode - rvm: ruby-head From d2a5bb4c4e6630912de3351fbf2a8447d1476055 Mon Sep 17 00:00:00 2001 From: Darren Cheng Date: Wed, 13 Jul 2016 14:32:07 -0700 Subject: [PATCH 4/5] Add dependency notes to README. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index f30186f..397cfbd 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,12 @@ gem 'grape-active_model_serializers' See [UPGRADING](UPGRADING.md) if you're upgrading from a previous version. +## Dependencies + +* >= Ruby v2.2 +* >= [grape](https://github.com/intridea/grape) v0.8.0 +* >= [active_model_serializers](https://github.com/rails-api/active_model_serializers) v0.10.0 + ## Usage ### Require grape-active_model_serializers From 8f1687b7f6a306d37bd39c95955bc3724ece0965 Mon Sep 17 00:00:00 2001 From: Darren Cheng Date: Wed, 13 Jul 2016 14:34:20 -0700 Subject: [PATCH 5/5] Ensure grape version is >= v0.8.0. --- grape-active_model_serializers.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grape-active_model_serializers.gemspec b/grape-active_model_serializers.gemspec index c81cdc9..9ce51c8 100644 --- a/grape-active_model_serializers.gemspec +++ b/grape-active_model_serializers.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |gem| gem.version = Grape::ActiveModelSerializers::VERSION gem.licenses = ['MIT'] - gem.add_dependency 'grape' + gem.add_dependency 'grape', '>= 0.8.0' gem.add_dependency 'active_model_serializers', '>= 0.10.0' gem.add_development_dependency 'listen', '~> 3.0.7'