From 06fcd34807e5964f7b90d63194fdb2d6494bbaec Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Sun, 19 Nov 2017 23:55:46 -0600 Subject: [PATCH 1/5] Follows https://github.com/rails-api/active_model_serializers/pull/2100 --- lib/active_model/serializer.rb | 10 ++- .../adapter/attributes.rb | 19 ++++++ test/adapter/json/fields_test.rb | 63 +++++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 test/adapter/json/fields_test.rb diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 04dcf8f0..864eba7b 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -365,6 +365,9 @@ module ActiveModel def serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance) adapter_options ||= {} options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options) + if (fieldset = adapter_options[:fieldset]) + options[:fields] = fieldset.fields_for(json_key) + end resource = attributes_hash(adapter_options, options, adapter_instance) relationships = associations_hash(adapter_options, options, adapter_instance) resource.merge(relationships) @@ -379,7 +382,12 @@ module ActiveModel # Used by adapter as resource root. def json_key - root || _type || object.class.model_name.to_s.underscore + root || _type || + begin + object.class.model_name.to_s.underscore + rescue ArgumentError + 'anonymous_object' + end end def read_attribute_for_serialization(attr) diff --git a/lib/active_model_serializers/adapter/attributes.rb b/lib/active_model_serializers/adapter/attributes.rb index c0674e5b..af95797a 100644 --- a/lib/active_model_serializers/adapter/attributes.rb +++ b/lib/active_model_serializers/adapter/attributes.rb @@ -3,6 +3,11 @@ module ActiveModelSerializers module Adapter class Attributes < Base + def initialize(*) + super + instance_options[:fieldset] ||= ActiveModel::Serializer::Fieldset.new(fields_to_fieldset(instance_options.delete(:fields))) + end + def serializable_hash(options = nil) options = serialization_options(options) options[:fields] ||= instance_options[:fields] @@ -10,6 +15,20 @@ module ActiveModelSerializers self.class.transform_key_casing!(serialized_hash, instance_options) end + + def fields_to_fieldset(fields) + return fields if fields.nil? + resource_fields = [] + relationship_fields = {} + fields.each do |field| + case field + when Symbol, String then resource_fields << field + when Hash then relationship_fields.merge!(field) + else fail ArgumentError, "Unknown conversion of fields to fieldset: '#{field.inspect}' in '#{fields.inspect}'" + end + end + relationship_fields.merge(serializer.json_key.to_sym => resource_fields) + end end end end diff --git a/test/adapter/json/fields_test.rb b/test/adapter/json/fields_test.rb new file mode 100644 index 00000000..f44a242f --- /dev/null +++ b/test/adapter/json/fields_test.rb @@ -0,0 +1,63 @@ +require 'test_helper' + +module ActiveModelSerializers + module Adapter + class Json + class FieldsTest < ActiveSupport::TestCase + class Post < ::Model + attributes :title, :body + associations :author, :comments + end + class Author < ::Model + attributes :name, :birthday + end + class Comment < ::Model + attributes :title, :body + associations :author, :post + end + + class PostSerializer < ActiveModel::Serializer + type 'posts' + attributes :title, :body + belongs_to :author + has_many :comments + end + + class AuthorSerializer < ActiveModel::Serializer + attributes :name, :birthday + end + + class CommentSerializer < ActiveModel::Serializer + type 'comments' + attributes :title, :body + belongs_to :author + end + + def setup + @author = Author.new(id: 1, name: 'Lucas', birthday: '10.01.1990') + @comment1 = Comment.new(id: 7, body: 'cool', author: @author) + @comment2 = Comment.new(id: 12, body: 'awesome', author: @author) + @post = Post.new(id: 1337, title: 'Title 1', body: 'Body 1', + author: @author, comments: [@comment1, @comment2]) + @comment1.post = @post + @comment2.post = @post + end + + def test_fields_attributes + fields = [:title] + hash = serializable(@post, adapter: :json, fields: fields, include: []).serializable_hash + expected = { title: 'Title 1' } + assert_equal(expected, hash[:posts]) + end + + def test_fields_included + fields = [:title, { comments: [:body] }] + hash = serializable(@post, adapter: :json, include: [:comments], fields: fields).serializable_hash + expected = [{ body: @comment1.body }, { body: @comment2.body }] + + assert_equal(expected, hash[:posts][:comments]) + end + end + end + end +end From a9cb0971098d0638057c7c7c8a15c981ea34a2d8 Mon Sep 17 00:00:00 2001 From: Wasif Hossain Date: Thu, 21 Feb 2019 03:03:35 +0600 Subject: [PATCH 2/5] Refactoring --- lib/active_model_serializers/adapter/attributes.rb | 4 +++- test/adapter/json/fields_test.rb | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/active_model_serializers/adapter/attributes.rb b/lib/active_model_serializers/adapter/attributes.rb index af95797a..3372e2be 100644 --- a/lib/active_model_serializers/adapter/attributes.rb +++ b/lib/active_model_serializers/adapter/attributes.rb @@ -16,6 +16,8 @@ module ActiveModelSerializers self.class.transform_key_casing!(serialized_hash, instance_options) end + private + def fields_to_fieldset(fields) return fields if fields.nil? resource_fields = [] @@ -27,7 +29,7 @@ module ActiveModelSerializers else fail ArgumentError, "Unknown conversion of fields to fieldset: '#{field.inspect}' in '#{fields.inspect}'" end end - relationship_fields.merge(serializer.json_key.to_sym => resource_fields) + relationship_fields.merge!(serializer.json_key.to_sym => resource_fields) end end end diff --git a/test/adapter/json/fields_test.rb b/test/adapter/json/fields_test.rb index f44a242f..04da0017 100644 --- a/test/adapter/json/fields_test.rb +++ b/test/adapter/json/fields_test.rb @@ -17,7 +17,7 @@ module ActiveModelSerializers end class PostSerializer < ActiveModel::Serializer - type 'posts' + type 'post' attributes :title, :body belongs_to :author has_many :comments @@ -28,7 +28,7 @@ module ActiveModelSerializers end class CommentSerializer < ActiveModel::Serializer - type 'comments' + type 'comment' attributes :title, :body belongs_to :author end @@ -47,7 +47,7 @@ module ActiveModelSerializers fields = [:title] hash = serializable(@post, adapter: :json, fields: fields, include: []).serializable_hash expected = { title: 'Title 1' } - assert_equal(expected, hash[:posts]) + assert_equal(expected, hash[:post]) end def test_fields_included @@ -55,7 +55,7 @@ module ActiveModelSerializers hash = serializable(@post, adapter: :json, include: [:comments], fields: fields).serializable_hash expected = [{ body: @comment1.body }, { body: @comment2.body }] - assert_equal(expected, hash[:posts][:comments]) + assert_equal(expected, hash[:post][:comments]) end end end From 807e160b9c5473c42ffb12ad18de64a125733599 Mon Sep 17 00:00:00 2001 From: Wasif Hossain Date: Thu, 21 Feb 2019 03:19:42 +0600 Subject: [PATCH 3/5] Add missing frozen string literal comment --- test/adapter/json/fields_test.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/adapter/json/fields_test.rb b/test/adapter/json/fields_test.rb index 04da0017..5e1f570a 100644 --- a/test/adapter/json/fields_test.rb +++ b/test/adapter/json/fields_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' module ActiveModelSerializers From 96303af45f964aee916c0e44c954d5f87d7c63e2 Mon Sep 17 00:00:00 2001 From: Wasif Hossain Date: Tue, 23 Apr 2019 15:14:35 +0600 Subject: [PATCH 4/5] Add changelog entries for this PR and #2327 --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c638d73..2d257f31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,14 @@ Breaking changes: Features: +- [#2327](https://github.com/rails-api/active_model_serializers/pull/2327) Add support for Ruby 2.6 on Travis CI (@wasifhossain) + Fixes: + - [#2319](https://github.com/rails-api/active_model_serializers/pull/2319) Fixes #2316. (@kylekeesling) - - Fix Rails 6.0 deprication warnings - - update test fixture schema to use `timestamps` instead of `timestamp` + - Fix Rails 6.0 deprication warnings + - update test fixture schema to use `timestamps` instead of `timestamp` +- [#2223](https://github.com/rails-api/active_model_serializers/pull/2223) Support Fieldset in Attributes/JSON adapters documented in [docs/general/fields.md](https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/general/fields.md) that worked partially before (@bf4) Misc: From c77fddadd42097228e16574db3ccb8bb0f79f678 Mon Sep 17 00:00:00 2001 From: Wasif Hossain Date: Tue, 23 Apr 2019 15:18:18 +0600 Subject: [PATCH 5/5] Mention current rails version for #2327 ruby2.6/rails4.2 monkeypatch --- test/support/ruby_2_6_rails_4_2_patch.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/support/ruby_2_6_rails_4_2_patch.rb b/test/support/ruby_2_6_rails_4_2_patch.rb index 9e250339..768e9430 100644 --- a/test/support/ruby_2_6_rails_4_2_patch.rb +++ b/test/support/ruby_2_6_rails_4_2_patch.rb @@ -13,6 +13,12 @@ if RUBY_VERSION >= '2.6.0' end end else - puts 'Monkeypatch for ActionController::TestResponse no longer needed' + msg = 'Monkeypatch for ActionController::TestResponse not needed for '\ + 'Rails 5+. We can drop this patch once we drop support for Rails < 5. '\ + "Current Rails version: #{ENV['RAILS_VERSION']}" + + puts + puts "\033[33m **** #{msg} **** \033[0m" + puts end end