diff --git a/.rubocop.yml b/.rubocop.yml
deleted file mode 100644
index 82f07656..00000000
--- a/.rubocop.yml
+++ /dev/null
@@ -1,105 +0,0 @@
-AllCops:
- TargetRubyVersion: 2.1
- Exclude:
- - !ruby/regexp /(vendor|bundle|bin|db|tmp)\/.*/
- DisplayCopNames: true
- DisplayStyleGuide: true
- # https://github.com/bbatsov/rubocop/blob/master/manual/caching.md
- # https://github.com/bbatsov/rubocop/blob/e8680418b351491e111a18cf5b453fc07a3c5239/config/default.yml#L60-L77
- UseCache: true
- CacheRootDirectory: tmp
-
-Rails:
- Enabled: true
-
-Lint/NestedMethodDefinition:
- Enabled: false
- Exclude:
- - test/action_controller/serialization_test.rb
-
-Style/Alias:
- EnforcedStyle: prefer_alias
-
-Style/StringLiterals:
- EnforcedStyle: single_quotes
-
-Metrics/AbcSize:
- Max: 35 # TODO: Lower to 15
-
-Metrics/ClassLength:
- Max: 261 # TODO: Lower to 100
- Exclude:
- - test/**/*.rb
-
-Metrics/CyclomaticComplexity:
- Max: 7 # TODO: Lower to 6
-
-Metrics/LineLength:
- Max: 251 # TODO: Lower to 80
-
-Metrics/MethodLength:
- Max: 106 # TODO: Lower to 10
-
-Metrics/PerceivedComplexity:
- Max: 9 # TODO: Lower to 7
-
-Style/AlignParameters:
- EnforcedStyle: with_fixed_indentation
-
-Style/ClassAndModuleChildren:
- EnforcedStyle: nested
-
-Style/Documentation:
- Enabled: false
-
-Style/MissingElse:
- Enabled: true
- EnforcedStyle: case
-
-Style/EmptyElse:
- EnforcedStyle: empty
-
-Style/MultilineOperationIndentation:
- EnforcedStyle: indented
-
-Style/BlockDelimiters:
- Enabled: true
- EnforcedStyle: line_count_based
-
-Style/SignalException:
- EnforcedStyle: semantic
-
-Style/TrailingCommaInLiteral:
- EnforcedStyleForMultiline: no_comma
-
-Style/ConditionalAssignment:
- Enabled: false
-
-Style/DotPosition:
- EnforcedStyle: leading
-
-########## test_helper.rb sanity
-Style/EndBlock:
- Exclude:
- - test/test_helper.rb
-
-Style/SpecialGlobalVars:
- Exclude:
- - test/test_helper.rb
-
-Style/GlobalVars:
- Exclude:
- - test/test_helper.rb
-
-Style/AndOr:
- Exclude:
- - test/test_helper.rb
- - 'lib/active_model/serializer/lint.rb'
-
-Style/Not:
- Exclude:
- - test/test_helper.rb
-
-Style/ClassCheck:
- Exclude:
- - test/test_helper.rb
diff --git a/.simplecov b/.simplecov
deleted file mode 100644
index 955a6060..00000000
--- a/.simplecov
+++ /dev/null
@@ -1,110 +0,0 @@
-# https://github.com/colszowka/simplecov#using-simplecov-for-centralized-config
-# see https://github.com/colszowka/simplecov/blob/master/lib/simplecov/defaults.rb
-# vim: set ft=ruby
-
-## DEFINE VARIABLES
-@minimum_coverage = ENV.fetch('COVERAGE_MINIMUM') {
- case (defined?(RUBY_ENGINE) && RUBY_ENGINE) || "ruby"
- when 'jruby', 'rbx'
- 96.0
- else
- 98.1
- end
-}.to_f.round(2)
-# rubocop:disable Style/DoubleNegation
-ENV['FULL_BUILD'] ||= ENV['CI']
-@running_ci = !!(ENV['FULL_BUILD'] =~ /\Atrue\z/i)
-@generate_report = @running_ci || !!(ENV['COVERAGE'] =~ /\Atrue\z/i)
-@output = STDOUT
-# rubocop:enable Style/DoubleNegation
-
-## CONFIGURE SIMPLECOV
-
-SimpleCov.profiles.define 'app' do
- coverage_dir 'coverage'
- load_profile 'test_frameworks'
-
- add_group 'Libraries', 'lib'
-
- add_group 'Long files' do |src_file|
- src_file.lines.count > 100
- end
- class MaxLinesFilter < SimpleCov::Filter
- def matches?(source_file)
- source_file.lines.count < filter_argument
- end
- end
- add_group 'Short files', MaxLinesFilter.new(5)
-
- # Exclude these paths from analysis
- add_filter '/config/'
- add_filter '/db/'
- add_filter 'tasks'
- add_filter '/.bundle/'
-end
-
-## START TRACKING COVERAGE (before activating SimpleCov)
-require 'coverage'
-Coverage.start
-
-## ADD SOME CUSTOM REPORTING AT EXIT
-SimpleCov.at_exit do
- next if $! and not ($!.kind_of? SystemExit and $!.success?)
-
- header = "#{'*' * 20} SimpleCov Results #{'*' * 20}"
- results = SimpleCov.result.format!.join("\n")
- exit_message = <<-EOF
-
-#{header}
-{{RESULTS}}
-{{FAILURE_MESSAGE}}
-
-#{'*' * header.size}
- EOF
- percent = Float(SimpleCov.result.covered_percent)
- if percent < @minimum_coverage
- failure_message = <<-EOF
-Spec coverage was not high enough: #{percent.round(2)}% is < #{@minimum_coverage}%
- EOF
- exit_message.sub!('{{RESULTS}}', results).sub!('{{FAILURE_MESSAGE}}', failure_message)
- @output.puts exit_message
- abort(failure_message) if @generate_report
- elsif @running_ci
- exit_message.sub!('{{RESULTS}}', results).sub!('{{FAILURE_MESSAGE}}', <<-EOF)
-Nice job! Spec coverage (#{percent.round(2)}%) is still at or above #{@minimum_coverage}%
- EOF
- @output.puts exit_message
- end
-end
-
-## CAPTURE CONFIG IN CLOSURE 'AppCoverage.start'
-## to defer running until test/test_helper.rb is loaded.
-# rubocop:disable Style/MultilineBlockChain
-AppCoverage = Class.new do
- def initialize(&block)
- @block = block
- end
-
- def start
- @block.call
- end
-end.new do
- SimpleCov.start 'app'
- if @generate_report
- if @running_ci
- require 'codeclimate-test-reporter'
- @output.puts '[COVERAGE] Running with SimpleCov Simple Formatter and CodeClimate Test Reporter'
- formatters = [
- SimpleCov::Formatter::SimpleFormatter,
- CodeClimate::TestReporter::Formatter
- ]
- else
- @output.puts '[COVERAGE] Running with SimpleCov HTML Formatter'
- formatters = [SimpleCov::Formatter::HTMLFormatter]
- end
- else
- formatters = []
- end
- SimpleCov.formatters = formatters
-end
-# rubocop:enable Style/MultilineBlockChain
diff --git a/.travis.yml b/.travis.yml
index 9aff1edc..b48fe610 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,54 +2,9 @@ language: ruby
sudo: false
-rvm:
- - 2.1
- - 2.2.6
- - 2.3.3
- - ruby-head
- - jruby-9.1.5.0 # is precompiled per http://rubies.travis-ci.org/
- - jruby-head
-
-jdk:
- - oraclejdk8
-
-before_install:
- - gem update --system
- - rvm @global do gem uninstall bundler -a -x
- - rvm @global do gem install bundler -v 1.13.7
-install: bundle install --path=vendor/bundle --retry=3 --jobs=3
cache:
directories:
- vendor/bundle
script:
- - bundle exec rake ci
-after_success:
- - codeclimate-test-reporter
-env:
- global:
- - "JRUBY_OPTS='--dev -J-Xmx1024M --debug'"
- matrix:
- - "RAILS_VERSION=4.1"
- - "RAILS_VERSION=4.2"
- - "RAILS_VERSION=5.0"
- - "RAILS_VERSION=master"
-
-matrix:
- exclude:
- - rvm: 2.1
- env: RAILS_VERSION=master
- - rvm: jruby-9.1.5.0
- env: RAILS_VERSION=master
- - rvm: jruby-head
- env: RAILS_VERSION=master
- - rvm: 2.1
- env: RAILS_VERSION=5.0
- - rvm: jruby-9.1.5.0
- env: RAILS_VERSION=5.0
- - rvm: jruby-head
- env: RAILS_VERSION=5.0
- allow_failures:
- - rvm: ruby-head
- - rvm: jruby-head
- fast_finish: true
+ - true
diff --git a/CHANGELOG-0-08.md b/CHANGELOG-0-08.md
new file mode 100644
index 00000000..eec4e286
--- /dev/null
+++ b/CHANGELOG-0-08.md
@@ -0,0 +1,92 @@
+## 0.08.x
+
+### v0.8.3 (2014/12/10 14:45 +00:00)
+- [#753](https://github.com/rails-api/active_model_serializers/pull/753) Test against Ruby 2.2 on Travis CI (@tricknotes)
+- [#745](https://github.com/rails-api/active_model_serializers/pull/745) Missing a word (@jockee)
+
+### v0.8.2 (2014/09/01 21:00 +00:00)
+- [#612](https://github.com/rails-api/active_model_serializers/pull/612) Feature/adapter (@bolshakov)
+ * adds adapters pattern
+- [#615](https://github.com/rails-api/active_model_serializers/pull/615) Rails does not support const_defined? in development mode (@tpitale)
+- [#613](https://github.com/rails-api/active_model_serializers/pull/613) README: typo fix on attributes (@spk)
+- [#614](https://github.com/rails-api/active_model_serializers/pull/614) Fix rails 4.0.x build. (@arthurnn)
+- [#610](https://github.com/rails-api/active_model_serializers/pull/610) ArraySerializer (@bolshakov)
+- [#607](https://github.com/rails-api/active_model_serializers/pull/607) ruby syntax highlights (@zigomir)
+- [#602](https://github.com/rails-api/active_model_serializers/pull/602) Add DSL for associations (@JordanFaust)
+
+### 0.8.1 (May 6, 2013)
+
+* Fix bug whereby a serializer using 'options' would blow up.
+
+### 0.8.0 (May 5, 2013)
+
+* Attributes can now have optional types.
+
+* A new DefaultSerializer ensures that POROs behave the same way as ActiveModels.
+
+* If you wish to override ActiveRecord::Base#to_Json, you can now require
+ 'active_record/serializer_override'. We don't recommend you do this, but
+ many users do, so we've left it optional.
+
+* Fixed a bug where ActionController wouldn't always have MimeResponds.
+
+* An optinal caching feature allows you to cache JSON & hashes that AMS uses.
+ Adding 'cached true' to your Serializers will turn on this cache.
+
+* URL helpers used inside of Engines now work properly.
+
+* Serializers now can filter attributes with `only` and `except`:
+
+ ```
+ UserSerializer.new(user, only: [:first_name, :last_name])
+ UserSerializer.new(user, except: :first_name)
+ ```
+
+* Basic Mongoid support. We now include our mixins in the right place.
+
+* On Ruby 1.8, we now generate an `id` method that properly serializes `id`
+ columns. See issue #127 for more.
+
+* Add an alias for `scope` method to be the name of the context. By default
+ this is `current_user`. The name is automatically set when using
+ `serialization_scope` in the controller.
+
+* Pass through serialization options (such as `:include`) when a model
+ has no serializer defined.
+
+## [0.7.0 (March 6, 2013)](https://github.com/rails-api/active_model_serializers/commit/fabdc621ff97fbeca317f6301973dd4564b9e695)
+
+* ```embed_key``` option to allow embedding by attributes other than IDs
+* Fix rendering nil with custom serializer
+* Fix global ```self.root = false```
+* Add support for specifying the serializer for an association as a String
+* Able to specify keys on the attributes method
+* Serializer Reloading via ActiveSupport::DescendantsTracker
+* Reduce double map to once; Fixes datamapper eager loading.
+
+## 0.6.0 (October 22, 2012)
+
+* Serialize sets properly
+* Add root option to ArraySerializer
+* Support polymorphic associations
+* Support :each_serializer in ArraySerializer
+* Add `scope` method to easily access the scope in the serializer
+* Fix regression with Rails 3.2.6; add Rails 4 support
+* Allow serialization_scope to be disabled with serialization_scope nil
+* Array serializer should support pure ruby objects besides serializers
+
+## 0.05.x
+
+### [0.5.2 (June 5, 2012)](https://github.com/rails-api/active_model_serializers/commit/615afd125c260432d456dc8be845867cf87ea118#diff-0c5c12f311d3b54734fff06069efd2ac)
+
+### [0.5.1 (May 23, 2012)](https://github.com/rails-api/active_model_serializers/commit/00194ec0e41831802fcbf893a34c0bb0853ebe14#diff-0c5c12f311d3b54734fff06069efd2ac)
+
+### [0.5.0 (May 16, 2012)](https://github.com/rails-api/active_model_serializers/commit/33d4842dcd35c7167b0b33fc0abcf00fb2c92286)
+
+* First tagged version
+* Changes generators to always generate an ApplicationSerializer
+
+## [0.1.0 (December 21, 2011)](https://github.com/rails-api/active_model_serializers/commit/1e0c9ef93b96c640381575dcd30be07ac946818b)
+
+## First Commit as [Rails Serializers 0.0.1](https://github.com/rails-api/active_model_serializers/commit/d72b66d4c5355b0ff0a75a04895fcc4ea5b0c65e)
+ (December 1, 2011).
diff --git a/CHANGELOG-0-09.md b/CHANGELOG-0-09.md
new file mode 100644
index 00000000..a36e8e9b
--- /dev/null
+++ b/CHANGELOG-0-09.md
@@ -0,0 +1,74 @@
+## 0.09.x
+
+### v0.9.3 (2015/01/21 20:29 +00:00)
+
+Features:
+- [#774](https://github.com/rails-api/active_model_serializers/pull/774) Fix nested include attributes (@nhocki)
+- [#771](https://github.com/rails-api/active_model_serializers/pull/771) Make linked resource type names consistent with root names (@sweatypitts)
+- [#696](https://github.com/rails-api/active_model_serializers/pull/696) Explicitly set serializer for associations (@ggordon)
+- [#700](https://github.com/rails-api/active_model_serializers/pull/700) sparse fieldsets (@arenoir)
+- [#768](https://github.com/rails-api/active_model_serializers/pull/768) Adds support for `meta` and `meta_key` attribute (@kurko)
+
+### v0.9.1 (2014/12/04 11:54 +00:00)
+- [#707](https://github.com/rails-api/active_model_serializers/pull/707) A Friendly Note on Which AMS Version to Use (@jherdman)
+- [#730](https://github.com/rails-api/active_model_serializers/pull/730) Fixes nested has_many links in JSONAPI (@kurko)
+- [#718](https://github.com/rails-api/active_model_serializers/pull/718) Allow overriding the adapter with render option (@ggordon)
+- [#720](https://github.com/rails-api/active_model_serializers/pull/720) Rename attribute with :key (0.8.x compatibility) (@ggordon)
+- [#728](https://github.com/rails-api/active_model_serializers/pull/728) Use type as key for linked resources (@kurko)
+- [#729](https://github.com/rails-api/active_model_serializers/pull/729) Use the new beta build env on Travis (@joshk)
+- [#703](https://github.com/rails-api/active_model_serializers/pull/703) Support serializer and each_serializer options in renderer (@ggordon, @mieko)
+- [#727](https://github.com/rails-api/active_model_serializers/pull/727) Includes links inside of linked resources (@kurko)
+- [#726](https://github.com/rails-api/active_model_serializers/pull/726) Bugfix: include nested has_many associations (@kurko)
+- [#722](https://github.com/rails-api/active_model_serializers/pull/722) Fix infinite recursion (@ggordon)
+- [#1](https://github.com/rails-api/active_model_serializers/pull/1) Allow for the implicit use of ArraySerializer when :each_serializer is specified (@mieko)
+- [#692](https://github.com/rails-api/active_model_serializers/pull/692) Include 'linked' member for json-api collections (@ggordon)
+- [#714](https://github.com/rails-api/active_model_serializers/pull/714) Define as_json instead of to_json (@guilleiguaran)
+- [#710](https://github.com/rails-api/active_model_serializers/pull/710) JSON-API: Don't include linked section if associations are empty (@guilleiguaran)
+- [#711](https://github.com/rails-api/active_model_serializers/pull/711) Fixes rbx gems bundling on TravisCI (@kurko)
+- [#709](https://github.com/rails-api/active_model_serializers/pull/709) Add type key when association name is different than object type (@guilleiguaran)
+- [#708](https://github.com/rails-api/active_model_serializers/pull/708) Handle correctly null associations (@guilleiguaran)
+- [#691](https://github.com/rails-api/active_model_serializers/pull/691) Fix embed option for associations (@jacob-s-son)
+- [#689](https://github.com/rails-api/active_model_serializers/pull/689) Fix support for custom root in JSON-API adapter (@guilleiguaran)
+- [#685](https://github.com/rails-api/active_model_serializers/pull/685) Serialize ids as strings in JSON-API adapter (@guilleiguaran)
+- [#684](https://github.com/rails-api/active_model_serializers/pull/684) Refactor adapters to implement support for array serialization (@guilleiguaran)
+- [#682](https://github.com/rails-api/active_model_serializers/pull/682) Include root by default in JSON-API serializers (@guilleiguaran)
+- [#625](https://github.com/rails-api/active_model_serializers/pull/625) Add DSL for urls (@JordanFaust)
+- [#677](https://github.com/rails-api/active_model_serializers/pull/677) Add support for embed: :ids option for in associations (@guilleiguaran)
+- [#681](https://github.com/rails-api/active_model_serializers/pull/681) Check superclasses for Serializers (@quainjn)
+- [#680](https://github.com/rails-api/active_model_serializers/pull/680) Add support for root keys (@NullVoxPopuli)
+- [#675](https://github.com/rails-api/active_model_serializers/pull/675) Support Rails 4.2.0 (@tricknotes)
+- [#667](https://github.com/rails-api/active_model_serializers/pull/667) Require only activemodel instead of full rails (@guilleiguaran)
+- [#653](https://github.com/rails-api/active_model_serializers/pull/653) Add "_test" suffix to JsonApi::HasManyTest filename. (@alexgenco)
+- [#631](https://github.com/rails-api/active_model_serializers/pull/631) Update build badge URL (@craiglittle)
+
+### 0.9.0.alpha1 - January 7, 2014
+
+### 0.9.0.pre
+
+* The following methods were removed
+ - Model#active\_model\_serializer
+ - Serializer#include!
+ - Serializer#include?
+ - Serializer#attr\_disabled=
+ - Serializer#cache
+ - Serializer#perform\_caching
+ - Serializer#schema (needs more discussion)
+ - Serializer#attribute
+ - Serializer#include\_#{name}? (filter method added)
+ - Serializer#attributes (took a hash)
+
+* The following things were added
+ - Serializer#filter method
+ - CONFIG object
+
+* Remove support for ruby 1.8 versions.
+
+* Require rails >= 3.2.
+
+* Serializers for associations are being looked up in a parent serializer's namespace first. Same with controllers' namespaces.
+
+* Added a "prefix" option in case you want to use a different version of serializer.
+
+* Serializers default namespace can be set in `default_serializer_options` and inherited by associations.
+
+* [Beginning of rewrite: c65d387705ec534db171712671ba7fcda4f49f68](https://github.com/rails-api/active_model_serializers/commit/c65d387705ec534db171712671ba7fcda4f49f68)
diff --git a/CHANGELOG-0-10.md b/CHANGELOG-0-10.md
new file mode 100644
index 00000000..fbe0bd21
--- /dev/null
+++ b/CHANGELOG-0-10.md
@@ -0,0 +1,466 @@
+## 0.10.x
+
+### [0-10-stable (unreleased)](https://github.com/rails-api/active_model_serializers/compare/v0.10.6...0-10-stable)
+
+Breaking changes:
+
+Features:
+
+Fixes:
+
+Misc:
+
+### [v0.10.6 (2017-05-01)](https://github.com/rails-api/active_model_serializers/compare/v0.10.5...v0.10.6)
+
+Fixes:
+
+- [#1857](https://github.com/rails-api/active_model_serializers/pull/1857) JSON:API does not load belongs_to relation to get identifier id. (@bf4)
+- [#2119](https://github.com/rails-api/active_model_serializers/pull/2119) JSON:API returns null resource object identifier when 'id' is null. (@bf4)
+- [#2093](https://github.com/rails-api/active_model_serializers/pull/2093) undef problematic Serializer methods: display, select. (@bf4)
+
+Misc:
+
+- [#2104](https://github.com/rails-api/active_model_serializers/pull/2104) Documentation for serializers and rendering. (@cassidycodes)
+- [#2081](https://github.com/rails-api/active_model_serializers/pull/2081) Documentation for `include` option in adapters. (@charlie-wasp)
+- [#2120](https://github.com/rails-api/active_model_serializers/pull/2120) Documentation for association options: foreign_key, type, class_name, namespace. (@bf4)
+
+### [v0.10.5 (2017-03-07)](https://github.com/rails-api/active_model_serializers/compare/v0.10.4...v0.10.5)
+
+Breaking changes:
+
+Features:
+
+- [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) ActiveModelSerializers::Model#attributes. Originally in [#1982](https://github.com/rails-api/active_model_serializers/pull/1982). (@bf4)
+- [#2057](https://github.com/rails-api/active_model_serializers/pull/2057)
+ Update version constraint for jsonapi-renderer to `['>= 0.1.1.beta1', '< 0.2']`
+ (@jaredbeck)
+
+Fixes:
+
+- [#2022](https://github.com/rails-api/active_model_serializers/pull/2022) Mutation of ActiveModelSerializers::Model now changes the attributes. Originally in [#1984](https://github.com/rails-api/active_model_serializers/pull/1984). (@bf4)
+
+Misc:
+
+- [#2055](https://github.com/rails-api/active_model_serializers/pull/2055)
+ Replace deprecated dependency jsonapi with jsonapi-renderer. (@jaredbeck)
+- [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) Make test attributes explicit. Tests have Model#associations. (@bf4)
+- [#1981](https://github.com/rails-api/active_model_serializers/pull/1981) Fix relationship link documentation. (@groyoh)
+- [#2035](https://github.com/rails-api/active_model_serializers/pull/2035) Document how to disable the logger. (@MSathieu)
+- [#2039](https://github.com/rails-api/active_model_serializers/pull/2039) Documentation fixes. (@biow0lf)
+
+### [v0.10.4 (2017-01-06)](https://github.com/rails-api/active_model_serializers/compare/v0.10.3...v0.10.4)
+
+Misc:
+
+- [#2005](https://github.com/rails-api/active_model_serializers/pull/2005) Update jsonapi runtime dependency to 0.1.1.beta6, support Ruby 2.4. (@kofronpi)
+- [#1993](https://github.com/rails-api/active_model_serializers/pull/1993) Swap out KeyTransform for CaseTransform gem for the possibility of native extension use. (@NullVoxPopuli)
+
+### [v0.10.3 (2016-11-21)](https://github.com/rails-api/active_model_serializers/compare/v0.10.2...v0.10.3)
+
+Fixes:
+
+- [#1973](https://github.com/rails-api/active_model_serializers/pull/1973) Fix namespace lookup for collections and has_many relationships (@groyoh)
+- [#1887](https://github.com/rails-api/active_model_serializers/pull/1887) Make the comment reflect what the function does (@johnnymo87)
+- [#1890](https://github.com/rails-api/active_model_serializers/issues/1890) Ensure generator inherits from ApplicationSerializer when available (@richmolj)
+- [#1922](https://github.com/rails-api/active_model_serializers/pull/1922) Make railtie an optional dependency in runtime (@ggpasqualino)
+- [#1930](https://github.com/rails-api/active_model_serializers/pull/1930) Ensure valid jsonapi when relationship has no links or data (@richmolj)
+
+Features:
+
+- [#1757](https://github.com/rails-api/active_model_serializers/pull/1757) Make serializer lookup chain configurable. (@NullVoxPopuli)
+- [#1968](https://github.com/rails-api/active_model_serializers/pull/1968) (@NullVoxPopuli)
+ - Add controller namespace to default controller lookup
+ - Provide a `namespace` render option
+ - document how set the namespace in the controller for implicit lookup.
+- [#1791](https://github.com/rails-api/active_model_serializers/pull/1791) (@bf4, @youroff, @NullVoxPopuli)
+ - Added `jsonapi_namespace_separator` config option.
+- [#1889](https://github.com/rails-api/active_model_serializers/pull/1889) Support key transformation for Attributes adapter (@iancanderson, @danbee)
+- [#1917](https://github.com/rails-api/active_model_serializers/pull/1917) Add `jsonapi_pagination_links_enabled` configuration option (@richmolj)
+- [#1797](https://github.com/rails-api/active_model_serializers/pull/1797) Only include 'relationships' when sideloading (@richmolj)
+
+Fixes:
+
+- [#1833](https://github.com/rails-api/active_model_serializers/pull/1833) Remove relationship links if they are null (@groyoh)
+- [#1881](https://github.com/rails-api/active_model_serializers/pull/1881) ActiveModelSerializers::Model correctly works with string keys (@yevhene)
+
+Misc:
+- [#1767](https://github.com/rails-api/active_model_serializers/pull/1767) Replace raising/rescuing `CollectionSerializer::NoSerializerError`,
+ throw/catch `:no_serializer`. (@bf4)
+- [#1839](https://github.com/rails-api/active_model_serializers/pull/1839) `fields` tests demonstrating usage for both attributes and relationships. (@NullVoxPopuli)
+- [#1812](https://github.com/rails-api/active_model_serializers/pull/1812) add a code of conduct (@corainchicago)
+
+- [#1878](https://github.com/rails-api/active_model_serializers/pull/1878) Cache key generation for serializers now uses `ActiveSupport::Cache.expand_cache_key` instead of `Array#join` by default and is also overridable. This change should be backward-compatible. (@markiz)
+
+- [#1799](https://github.com/rails-api/active_model_serializers/pull/1799) Add documentation for setting the adapter. (@cassidycodes)
+- [#1909](https://github.com/rails-api/active_model_serializers/pull/1909) Add documentation for relationship links. (@vasilakisfil, @NullVoxPopuli)
+- [#1959](https://github.com/rails-api/active_model_serializers/pull/1959) Add documentation for root. (@shunsuke227ono)
+- [#1967](https://github.com/rails-api/active_model_serializers/pull/1967) Improve type method documentation. (@yukideluxe)
+
+### [v0.10.2 (2016-07-05)](https://github.com/rails-api/active_model_serializers/compare/v0.10.1...v0.10.2)
+
+Fixes:
+- [#1814](https://github.com/rails-api/active_model_serializers/pull/1814) Ensuring read_multi works with fragment cache
+- [#1848](https://github.com/rails-api/active_model_serializers/pull/1848) Redefine associations on inherited serializers. (@EhsanYousefi)
+
+Misc:
+- [#1808](https://github.com/rails-api/active_model_serializers/pull/1808) Adds documentation for `fields` option. (@luizkowalski)
+
+### [v0.10.1 (2016-06-16)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0...v0.10.1)
+
+Features:
+- [#1668](https://github.com/rails-api/active_model_serializers/pull/1668) Exclude nil and empty links. (@sigmike)
+- [#1426](https://github.com/rails-api/active_model_serializers/pull/1426) Add ActiveModelSerializers.config.default_includes (@empact)
+
+Fixes:
+- [#1754](https://github.com/rails-api/active_model_serializers/pull/1754) Fixes #1759, Grape integration, improves serialization_context
+ missing error message on pagination. Document overriding CollectionSerializer#paginated?. (@bf4)
+ Moved serialization_context creation to Grape formatter, so resource serialization works without explicit calls to the `render` helper method.
+ Added Grape collection tests. (@onomated)
+- [#1287](https://github.com/rails-api/active_model_serializers/pull/1287) Pass `fields` options from adapter to serializer. (@vasilakisfil)
+- [#1710](https://github.com/rails-api/active_model_serializers/pull/1710) Prevent association loading when `include_data` option
+ is set to `false`. (@groyoh)
+- [#1747](https://github.com/rails-api/active_model_serializers/pull/1747) Improve jsonapi mime type registration for Rails 5 (@remear)
+
+Misc:
+- [#1734](https://github.com/rails-api/active_model_serializers/pull/1734) Adds documentation for conditional attribute (@lambda2)
+- [#1685](https://github.com/rails-api/active_model_serializers/pull/1685) Replace `IncludeTree` with `IncludeDirective` from the jsonapi gem.
+
+### [v0.10.0 (2016-05-17)](https://github.com/rails-api/active_model_serializers/compare/4a2d9853ba7...v0.10.0)
+
+Breaking changes:
+- [#1662](https://github.com/rails-api/active_model_serializers/pull/1662) Drop support for Rails 4.0 and Ruby 2.0.0. (@remear)
+
+Features:
+- [#1677](https://github.com/rails-api/active_model_serializers/pull/1677) Add `assert_schema`, `assert_request_schema`, `assert_request_response_schema`. (@bf4)
+- [#1697](https://github.com/rails-api/active_model_serializers/pull/1697) Include actual exception message with custom exceptions;
+ `Test::Schema` exceptions are now `Minitest::Assertion`s. (@bf4)
+- [#1699](https://github.com/rails-api/active_model_serializers/pull/1699) String/Lambda support for conditional attributes/associations (@mtsmfm)
+- [#1687](https://github.com/rails-api/active_model_serializers/pull/1687) Only calculate `_cache_digest` (in `cache_key`) when `skip_digest` is false. (@bf4)
+- [#1647](https://github.com/rails-api/active_model_serializers/pull/1647) Restrict usage of `serializable_hash` options
+ to the ActiveModel::Serialization and ActiveModel::Serializers::JSON interface. (@bf4)
+
+Fixes:
+- [#1700](https://github.com/rails-api/active_model_serializers/pull/1700) Support pagination link for Kaminari when no data is returned. (@iamnader)
+- [#1726](https://github.com/rails-api/active_model_serializers/pull/1726) Adds polymorphic option to association definition which includes association type/nesting in serializer (@cgmckeever)
+
+Misc:
+- [#1673](https://github.com/rails-api/active_model_serializers/pull/1673) Adds "How to" guide on using AMS with POROs (@DrSayre)
+- [#1730](https://github.com/rails-api/active_model_serializers/pull/1730) Adds documentation for overriding default serializer based on conditions (@groyoh/@cgmckeever)
+
+### [v0.10.0.rc5 (2016-04-04)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc4...v0.10.0.rc5)
+
+Breaking changes:
+
+- [#1645](https://github.com/rails-api/active_model_serializers/pull/1645) Changed :dashed key transform to :dash. (@remear)
+- [#1574](https://github.com/rails-api/active_model_serializers/pull/1574) Default key case for the JsonApi adapter changed to dashed. (@remear)
+
+Features:
+- [#1645](https://github.com/rails-api/active_model_serializers/pull/1645) Transform keys referenced in values. (@remear)
+- [#1650](https://github.com/rails-api/active_model_serializers/pull/1650) Fix serialization scope options `scope`, `scope_name`
+ take precedence over `serialization_scope` in the controller.
+ Fix tests that required tearing down dynamic methods. (@bf4)
+- [#1644](https://github.com/rails-api/active_model_serializers/pull/1644) Include adapter name in cache key so
+ that the same serializer can be cached per adapter. (@bf4 via #1346 by @kevintyll)
+- [#1642](https://github.com/rails-api/active_model_serializers/pull/1642) Prefer object.cache_key over the generated
+ cache key. (@bf4 via #1346 by @kevintyll)
+- [#1637](https://github.com/rails-api/active_model_serializers/pull/1637) Make references to 'ActionController::Base.cache_store' explicit
+ in order to avoid issues when application controllers inherit from 'ActionController::API'. (@ncuesta)
+- [#1633](https://github.com/rails-api/active_model_serializers/pull/1633) Yield 'serializer' to serializer association blocks. (@bf4)
+- [#1616](https://github.com/rails-api/active_model_serializers/pull/1616) SerializableResource handles no serializer like controller. (@bf4)
+- [#1618](https://github.com/rails-api/active_model_serializers/issues/1618) Get collection root key for
+ empty collection from explicit serializer option, when possible. (@bf4)
+- [#1574](https://github.com/rails-api/active_model_serializers/pull/1574) Provide key translation. (@remear)
+- [#1494](https://github.com/rails-api/active_model_serializers/pull/1494) Make serializers serializalbe
+ (using the Attributes adapter by default). (@bf4)
+- [#1550](https://github.com/rails-api/active_model_serializers/pull/1550) Add
+ Rails url_helpers to `SerializationContext` for use in links. (@remear, @bf4)
+- [#1004](https://github.com/rails-api/active_model_serializers/pull/1004) JSON API errors object implementation.
+ - Only implements `detail` and `source` as derived from `ActiveModel::Error`
+ - Provides checklist of remaining questions and remaining parts of the spec.
+- [#1515](https://github.com/rails-api/active_model_serializers/pull/1515) Adds support for symbols to the
+ `ActiveModel::Serializer.type` method. (@groyoh)
+- [#1504](https://github.com/rails-api/active_model_serializers/pull/1504) Adds the changes missing from #1454
+ and add more tests for resource identifier and relationship objects. Fix association block with link
+ returning `data: nil`.(@groyoh)
+- [#1372](https://github.com/rails-api/active_model_serializers/pull/1372) Support
+ cache_store.read_multi. (@LcpMarvel)
+- [#1018](https://github.com/rails-api/active_model_serializers/pull/1018) Add more tests and docs for top-level links. (@leandrocp)
+- [#1454](https://github.com/rails-api/active_model_serializers/pull/1454) Add support for
+ relationship-level links and meta attributes. (@beauby)
+- [#1340](https://github.com/rails-api/active_model_serializers/pull/1340) Add support for resource-level meta. (@beauby)
+
+Fixes:
+- [#1657](https://github.com/rails-api/active_model_serializers/pull/1657) Add missing missing require "active_support/json". (@andreaseger)
+- [#1661](https://github.com/rails-api/active_model_serializers/pull/1661) Fixes `read_attribute_for_serialization` not
+ seeing methods defined in serialization superclass (#1653, #1658, #1660), introduced in #1650. (@bf4)
+- [#1651](https://github.com/rails-api/active_model_serializers/pull/1651) Fix deserialization of nil relationships. (@NullVoxPopuli)
+- [#1480](https://github.com/rails-api/active_model_serializers/pull/1480) Fix setting of cache_store from Rails configuration. (@bf4)
+ Fix unintentional mutating of value in memory cache store. (@groyoh)
+- [#1622](https://github.com/rails-api/active_model_serializers/pull/1622) Fragment cache changed from per-record to per-serializer.
+ Now, two serializers that use the same model may be separately cached. (@lserman)
+- [#1478](https://github.com/rails-api/active_model_serializers/pull/1478) Cache store will now be correctly set when serializers are
+ loaded *before* Rails initializes. (@bf4)
+- [#1570](https://github.com/rails-api/active_model_serializers/pull/1570) Fixed pagination issue with last page size. (@bmorrall)
+- [#1516](https://github.com/rails-api/active_model_serializers/pull/1516) No longer return a nil href when only
+ adding meta to a relationship link. (@groyoh)
+- [#1458](https://github.com/rails-api/active_model_serializers/pull/1458) Preserve the serializer
+ type when fragment caching. (@bdmac)
+- [#1477](https://github.com/rails-api/active_model_serializers/pull/1477) Fix `fragment_cached?`
+ method to check if caching. (@bdmac)
+- [#1501](https://github.com/rails-api/active_model_serializers/pull/1501) Adds tests for SerializableResource::use_adapter?,doc typos (@domitian)
+- [#1488](https://github.com/rails-api/active_model_serializers/pull/1488) Require ActiveSupport's string inflections (@nate00)
+
+Misc:
+- [#1608](https://github.com/rails-api/active_model_serializers/pull/1608) Move SerializableResource to ActiveModelSerializers (@groyoh)
+- [#1602](https://github.com/rails-api/active_model_serializers/pull/1602) Add output examples to Adapters docs (@remear)
+- [#1557](https://github.com/rails-api/active_model_serializers/pull/1557) Update docs regarding overriding the root key (@Jwan622)
+- [#1471](https://github.com/rails-api/active_model_serializers/pull/1471) [Cleanup] Serializer caching is its own concern. (@bf4)
+- [#1482](https://github.com/rails-api/active_model_serializers/pull/1482) Document JSON API implementation defs and progress in class. (@bf4)
+- [#1551](https://github.com/rails-api/active_model_serializers/pull/1551) Added codebeat badge (@korzonek)
+- [#1527](https://github.com/rails-api/active_model_serializers/pull/1527) Refactor fragment cache class. (@groyoh)
+- [#1560](https://github.com/rails-api/active_model_serializers/pull/1560) Update rubocop and address its warnings. (@bf4 @groyoh)
+- [#1545](https://github.com/rails-api/active_model_serializers/pull/1545) Document how to pass arbitrary options to the
+ serializer (@CodedBeardedSignedTaylor)
+- [#1496](https://github.com/rails-api/active_model_serializers/pull/1496) Run all branches against JRuby on CI (@nadavshatz)
+- [#1559](https://github.com/rails-api/active_model_serializers/pull/1559) Add a deprecation DSL. (@bf4 @groyoh)
+- [#1543](https://github.com/rails-api/active_model_serializers/pull/1543) Add the changes missing from #1535. (@groyoh)
+- [#1535](https://github.com/rails-api/active_model_serializers/pull/1535) Move the adapter and adapter folder to
+ active_model_serializers folder and changes the module namespace. (@domitian @bf4)
+- [#1497](https://github.com/rails-api/active_model_serializers/pull/1497) Add JRuby-9000 to appveyor.yml(@corainchicago)
+- [#1420](https://github.com/rails-api/active_model_serializers/pull/1420) Adds tests and documentation for polymorphism(@marcgarreau)
+
+
+### [v0.10.0.rc4 (2016-01-27)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc3...v0.10.0.rc4)
+Breaking changes:
+
+- [#1360](https://github.com/rails-api/active_model_serializers/pull/1360)
+ [#1369](https://github.com/rails-api/active_model_serializers/pull/1369) Drop support for Ruby 1.9.3 (@karaAJC, @maurogeorge)
+- [#1131](https://github.com/rails-api/active_model_serializers/pull/1131) Remove Serializer#root_name (@beauby)
+- [#1138](https://github.com/rails-api/active_model_serializers/pull/1138) Introduce Adapter::Base (@bf4)
+ * Adapters now inherit Adapter::Base. 'Adapter' is now a module, no longer a class.
+ * using a class as a namespace that you also inherit from is complicated and circular at times i.e.
+ buggy (see https://github.com/rails-api/active_model_serializers/pull/1177)
+ * The class methods on Adapter aren't necessarily related to the instance methods, they're more
+ Adapter functions.
+ * named `Base` because it's a Rails-ism.
+ * It helps to isolate and highlight what the Adapter interface actually is.
+- [#1418](https://github.com/rails-api/active_model_serializers/pull/1418)
+ serialized collections now use the root option as is; now, only the
+ root derived from the serializer or object is always pluralized.
+
+Features:
+
+- [#1406](https://github.com/rails-api/active_model_serializers/pull/1406) Allow for custom dynamic values in JSON API links (@beauby)
+- [#1270](https://github.com/rails-api/active_model_serializers/pull/1270) Adds `assert_response_schema` test helper (@maurogeorge)
+- [#1099](https://github.com/rails-api/active_model_serializers/pull/1099) Adds `assert_serializer` test helper (@maurogeorge)
+- [#1403](https://github.com/rails-api/active_model_serializers/pull/1403) Add support for if/unless on attributes/associations (@beauby)
+- [#1248](https://github.com/rails-api/active_model_serializers/pull/1248) Experimental: Add support for JSON API deserialization (@beauby)
+- [#1378](https://github.com/rails-api/active_model_serializers/pull/1378) Change association blocks
+ to be evaluated in *serializer* scope, rather than *association* scope. (@bf4)
+ * Syntax changes from e.g.
+ `has_many :titles do customers.pluck(:title) end` (in #1356) to
+ `has_many :titles do object.customers.pluck(:title) end`
+- [#1356](https://github.com/rails-api/active_model_serializers/pull/1356) Add inline syntax for
+ attributes and associations (@bf4 @beauby @noahsilas)
+ * Allows defining attributes so that they don't conflict with existing methods. e.g. `attribute
+ :title do 'Mr. Topum Hat' end`
+ * Allows defining associations so that they don't conflict with existing methods. e.g. `has_many
+ :titles do customers.pluck(:title) end`
+ * Allows dynamic associations, as compared to compare to using
+ [`virtual_value`](https://github.com/rails-api/active_model_serializers/pull/1356#discussion_r47146466).
+ e.g. `has_many :reviews, virtual_value: [{ id: 1 }, { id: 2 }]`
+ * Removes dynamically defined methods on the serializer
+- [#1336](https://github.com/rails-api/active_model_serializers/pull/1336) Added support for Grape >= 0.13, < 1.0 (@johnhamelink)
+- [#1322](https://github.com/rails-api/active_model_serializers/pull/1322) Instrumenting rendering of resources (@bf4, @maurogeorge)
+- [#1291](https://github.com/rails-api/active_model_serializers/pull/1291) Add logging (@maurogeorge)
+- [#1272](https://github.com/rails-api/active_model_serializers/pull/1272) Add PORO serializable base class: ActiveModelSerializers::Model (@bf4)
+- [#1255](https://github.com/rails-api/active_model_serializers/pull/1255) Make more class attributes inheritable (@bf4)
+- [#1249](https://github.com/rails-api/active_model_serializers/pull/1249) Inheritance of serializer inheriting the cache configuration(@Rodrigora)
+- [#1247](https://github.com/rails-api/active_model_serializers/pull/1247) Add support for toplevel JSON API links (@beauby)
+- [#1246](https://github.com/rails-api/active_model_serializers/pull/1246) Add support for resource-level JSON API links (@beauby)
+- [#1225](https://github.com/rails-api/active_model_serializers/pull/1225) Better serializer lookup, use nested serializer when it exists (@beauby)
+- [#1213](https://github.com/rails-api/active_model_serializers/pull/1213) `type` directive for serializer to control type field with json-api adapter (@youroff)
+- [#1172](https://github.com/rails-api/active_model_serializers/pull/1172) Better serializer registration, get more than just the first module (@bf4)
+- [#1158](https://github.com/rails-api/active_model_serializers/pull/1158) Add support for wildcards in `include` option (@beauby)
+- [#1127](https://github.com/rails-api/active_model_serializers/pull/1127) Add support for nested
+ associations for JSON and Attributes adapters via the `include` option (@NullVoxPopuli, @beauby).
+- [#1050](https://github.com/rails-api/active_model_serializers/pull/1050) Add support for toplevel jsonapi member (@beauby, @bf4)
+- [#1251](https://github.com/rails-api/active_model_serializers/pull/1251) Rename ArraySerializer to
+ CollectionSerializer for clarity, add ActiveModelSerializers.config.collection_serializer (@bf4)
+- [#1295](https://github.com/rails-api/active_model_serializers/pull/1295) Add config `serializer_lookup_enabled` that,
+ when disabled, requires serializers to explicitly specified. (@trek)
+
+Fixes:
+
+- [#1352](https://github.com/rails-api/active_model_serializers/pull/1352) Fix generators; Isolate Rails-specifc code in Railties (@dgynn, @bf4)
+- [#1384](https://github.com/rails-api/active_model_serializers/pull/1384)Fix database state leaking across tests (@bf4)
+- [#1297](https://github.com/rails-api/active_model_serializers/pull/1297) Fix `fields` option to restrict relationships as well (@beauby)
+- [#1239](https://github.com/rails-api/active_model_serializers/pull/1239) Fix duplicates in JSON API compound documents (@beauby)
+- [#1214](https://github.com/rails-api/active_model_serializers/pull/1214) retrieve the key from the reflection options when building associations (@NullVoxPopuli, @hut8)
+- [#1358](https://github.com/rails-api/active_model_serializers/pull/1358) Handle serializer file paths with spaces (@rwstauner, @bf4)
+- [#1195](https://github.com/rails-api/active_model_serializers/pull/1195) Fix id override (@beauby)
+- [#1185](https://github.com/rails-api/active_model_serializers/pull/1185) Fix options passing in Json and Attributes adapters (@beauby)
+
+Misc:
+
+- [#1383](https://github.com/rails-api/active_model_serializers/pull/1383) Simplify reflections handling (@beauby)
+- [#1370](https://github.com/rails-api/active_model_serializers/pull/1370) Simplify attributes handling via a mixin (@beauby)
+- [#1301](https://github.com/rails-api/active_model_serializers/pull/1301) Mapping JSON API spec / schema to AMS (@bf4)
+- [#1271](https://github.com/rails-api/active_model_serializers/pull/1271) Handle no serializer source file to digest (@bf4)
+- [#1260](https://github.com/rails-api/active_model_serializers/pull/1260) Serialization and Cache Documentation (@bf4)
+- [#1259](https://github.com/rails-api/active_model_serializers/pull/1259) Add more info to CONTRIBUTING (@bf4)
+- [#1233](https://github.com/rails-api/active_model_serializers/pull/1233) Top-level meta and meta_key options no longer handled at serializer level (@beauby)
+- [#1232](https://github.com/rails-api/active_model_serializers/pull/1232) fields option no longer handled at serializer level (@beauby)
+- [#1220](https://github.com/rails-api/active_model_serializers/pull/1220) Remove empty rubocop.rake (@maurogeorge)
+- [#1178](https://github.com/rails-api/active_model_serializers/pull/1178) env CAPTURE_STDERR=false lets devs see hard failures (@bf4)
+- [#1177](https://github.com/rails-api/active_model_serializers/pull/1177) Remove Adapter autoloads in favor of require (@bf4)
+- [#1117](https://github.com/rails-api/active_model_serializers/pull/1117) FlattenJson adapter no longer inherits Json adapter, renamed to Attributes (@bf4)
+- [#1171](https://github.com/rails-api/active_model_serializers/pull/1171) add require statements to top of file (@shicholas)
+- [#1167](https://github.com/rails-api/active_model_serializers/pull/1167) Delegate Serializer.attributes to Serializer.attribute (@bf4)
+- [#1174](https://github.com/rails-api/active_model_serializers/pull/1174) Consistently refer to the 'JSON API' and the 'JsonApi' adapter (@bf4)
+- [#1173](https://github.com/rails-api/active_model_serializers/pull/1173) Comment private accessor warnings (@bf4)
+- [#1166](https://github.com/rails-api/active_model_serializers/pull/1166) Prefer methods over instance variables (@bf4)
+- [#1168](https://github.com/rails-api/active_model_serializers/pull/1168) Fix appveyor failure cache not being expired (@bf4)
+- [#1161](https://github.com/rails-api/active_model_serializers/pull/1161) Remove duplicate test helper (@bf4)
+- [#1360](https://github.com/rails-api/active_model_serializers/pull/1360) Update CI to test 2.2.2 -> 2.2.3 (@karaAJC)
+- [#1371](https://github.com/rails-api/active_model_serializers/pull/1371) Refactor, update, create documentation (@bf4)
+
+### [v0.10.0.rc3 (2015-09-16)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc2...v0.10.0.rc3)
+- [#1129](https://github.com/rails-api/active_model_serializers/pull/1129) Remove SerializableResource.serialize in favor of `.new` (@bf4)
+- [#1155](https://github.com/rails-api/active_model_serializers/pull/1155) Outside controller use tutorial (@CodedBeardedSignedTaylor)
+- [#1154](https://github.com/rails-api/active_model_serializers/pull/1154) Rubocop fixes for issues introduced by #1089 (@NullVoxPopuli)
+- [#1089](https://github.com/rails-api/active_model_serializers/pull/1089) Add ActiveModelSerializers.logger with default null device (@bf4)
+- [#1109](https://github.com/rails-api/active_model_serializers/pull/1109) Make better use of Minitest's lifecycle (@bf4)
+- [#1144](https://github.com/rails-api/active_model_serializers/pull/1144) Fix Markdown to adapters documentation (@bacarini)
+- [#1121](https://github.com/rails-api/active_model_serializers/pull/1121) Refactor `add_links` in JSONAPI adapter. (@beauby)
+- [#1150](https://github.com/rails-api/active_model_serializers/pull/1150) Remove legacy method accidentally reintroduced in #1017 (@beauby)
+- [#1149](https://github.com/rails-api/active_model_serializers/pull/1149) Update README with nested included association example. (@mattmueller)
+- [#1110](https://github.com/rails-api/active_model_serializers/pull/1110) Add lint tests for AR models (@beauby)
+- [#1131](https://github.com/rails-api/active_model_serializers/pull/1131) Extended format for JSONAPI `include` option (@beauby)
+ * adds extended format for `include` option to JsonApi adapter
+- [#1142](https://github.com/rails-api/active_model_serializers/pull/1142) Updating wording on cache expiry in README (@leighhalliday)
+- [#1140](https://github.com/rails-api/active_model_serializers/pull/1140) Fix typo in fieldset exception (@lautis)
+- [#1132](https://github.com/rails-api/active_model_serializers/pull/1132) Get rid of unnecessary instance variables, and implied dependencies. (@beauby)
+- [#1139](https://github.com/rails-api/active_model_serializers/pull/1139) Documentation for serializing resources without render (@PericlesTheo)
+- [#1017](https://github.com/rails-api/active_model_serializers/pull/1017) Make Adapters registerable so they are not namespace-constrained (@bf4)
+- [#1120](https://github.com/rails-api/active_model_serializers/pull/1120) Add windows platform to loading sqlite3 (@Eric-Guo)
+- [#1123](https://github.com/rails-api/active_model_serializers/pull/1123) Remove url options (@bacarini)
+- [#1093](https://github.com/rails-api/active_model_serializers/pull/1093) Factor `with_adapter` + force cache clear before each test. (@beauby)
+- [#1095](https://github.com/rails-api/active_model_serializers/pull/1095) Add documentation about configuration options. (@beauby)
+- [#1069](https://github.com/rails-api/active_model_serializers/pull/1069) Add test coverage; account for no artifacts on CI (@bf4)
+- [#1103](https://github.com/rails-api/active_model_serializers/pull/1103) Move `id` and `json_api_type` methods from `Serializer` to `JsonApi`. (@beauby)
+- [#1106](https://github.com/rails-api/active_model_serializers/pull/1106) Add Style enforcer (via Rubocop) (@bf4)
+- [#1079](https://github.com/rails-api/active_model_serializers/pull/1079) Add ArraySerializer#object like Serializer (@bf4)
+- [#1096](https://github.com/rails-api/active_model_serializers/pull/1096) Fix definition of serializer attributes with multiple calls to `attri… (@beauby)
+- [#1105](https://github.com/rails-api/active_model_serializers/pull/1105) Add ActiveRecord-backed fixtures. (@beauby)
+- [#1108](https://github.com/rails-api/active_model_serializers/pull/1108) Better lint (@bf4)
+- [#1102](https://github.com/rails-api/active_model_serializers/pull/1102) Remove remains of `embed` option. (@beauby)
+- [#1090](https://github.com/rails-api/active_model_serializers/pull/1090) Clarify AMS dependencies (@bf4)
+- [#1081](https://github.com/rails-api/active_model_serializers/pull/1081) Add configuration option to set resource type to singular/plural (@beauby)
+- [#1067](https://github.com/rails-api/active_model_serializers/pull/1067) Fix warnings (@bf4)
+- [#1066](https://github.com/rails-api/active_model_serializers/pull/1066) Adding appveyor to the project (@joaomdmoura, @Eric-Guo, @bf4)
+- [#1071](https://github.com/rails-api/active_model_serializers/pull/1071) Make testing suite running and pass in Windows (@Eric-Guo, @bf4)
+- [#1041](https://github.com/rails-api/active_model_serializers/pull/1041) Adding pagination links (@bacarini)
+ * adds support for `pagination links` at top level of JsonApi adapter
+- [#1063](https://github.com/rails-api/active_model_serializers/pull/1063) Lead by example: lint PORO model (@bf4)
+- [#1](https://github.com/rails-api/active_model_serializers/pull/1) Test caller line parsing and digesting (@bf4)
+- [#1048](https://github.com/rails-api/active_model_serializers/pull/1048) Let FlattenJson adapter decide it doesn't include meta (@bf4)
+- [#1060](https://github.com/rails-api/active_model_serializers/pull/1060) Update fragment cache to support namespaced objects (@aaronlerch)
+- [#1052](https://github.com/rails-api/active_model_serializers/pull/1052) Use underscored json_root when serializing a collection (@whatthewhat)
+- [#1051](https://github.com/rails-api/active_model_serializers/pull/1051) Fix some invalid JSON in docs (@tjschuck)
+- [#1049](https://github.com/rails-api/active_model_serializers/pull/1049) Fix incorrect s/options = {}/options ||= {} (@bf4)
+- [#1037](https://github.com/rails-api/active_model_serializers/pull/1037) allow for type attribute (@lanej)
+- [#1034](https://github.com/rails-api/active_model_serializers/pull/1034) allow id attribute to be overriden (@lanej)
+- [#1035](https://github.com/rails-api/active_model_serializers/pull/1035) Fixed Comments highlight (@artLopez)
+- [#1031](https://github.com/rails-api/active_model_serializers/pull/1031) Disallow to define multiple associations at once (@bolshakov)
+- [#1032](https://github.com/rails-api/active_model_serializers/pull/1032) Wrap railtie requirement with rescue (@elliotlarson)
+- [#1026](https://github.com/rails-api/active_model_serializers/pull/1026) Bump Version Number to 0.10.0.rc2 (@jfelchner)
+- [#985](https://github.com/rails-api/active_model_serializers/pull/985) Associations implementation refactoring (@bolshakov)
+- [#954](https://github.com/rails-api/active_model_serializers/pull/954) Encapsulate serialization in ActiveModel::SerializableResource (@bf4)
+- [#972](https://github.com/rails-api/active_model_serializers/pull/972) Capture app warnings on test run (@bf4)
+- [#1019](https://github.com/rails-api/active_model_serializers/pull/1019) Improve README.md (@baojjeu)
+- [#998](https://github.com/rails-api/active_model_serializers/pull/998) Changing root to model class name (@joaomdmoura)
+- [#1006](https://github.com/rails-api/active_model_serializers/pull/1006) Fix adapter inflection bug for api -> API (@bf4)
+- [#1016](https://github.com/rails-api/active_model_serializers/pull/1016) require rails/railtie before subclassing Rails::Railtie (@bf4)
+- [#1013](https://github.com/rails-api/active_model_serializers/pull/1013) Root option with empty array support (@vyrak, @mareczek)
+- [#994](https://github.com/rails-api/active_model_serializers/pull/994) Starting Docs structure (@joaomdmoura)
+- [#1007](https://github.com/rails-api/active_model_serializers/pull/1007) Bug fix for ArraySerializer json_key (@jiajiawang)
+- [#1003](https://github.com/rails-api/active_model_serializers/pull/1003) Fix transient test failures (@Rodrigora)
+- [#996](https://github.com/rails-api/active_model_serializers/pull/996) Add linter for serializable resource (@bf4)
+- [#990](https://github.com/rails-api/active_model_serializers/pull/990) Adding json-api meta test (@joaomdmoura)
+- [#984](https://github.com/rails-api/active_model_serializers/pull/984) Add option "key" to serializer associations (@Rodrigora)
+- [#982](https://github.com/rails-api/active_model_serializers/pull/982) Fix typo (@bf4)
+- [#981](https://github.com/rails-api/active_model_serializers/pull/981) Remove unused PORO#to_param (@bf4)
+- [#978](https://github.com/rails-api/active_model_serializers/pull/978) fix generators template bug (@regonn)
+- [#975](https://github.com/rails-api/active_model_serializers/pull/975) Fixes virtual value not being used (@GriffinHeart)
+- [#970](https://github.com/rails-api/active_model_serializers/pull/970) Fix transient tests failures (@Rodrigora)
+- [#962](https://github.com/rails-api/active_model_serializers/pull/962) Rendering objects that doesn't have serializers (@bf4, @joaomdmoura, @JustinAiken)
+- [#939](https://github.com/rails-api/active_model_serializers/pull/939) Use a more precise generated cache key (@aaronlerch)
+- [#971](https://github.com/rails-api/active_model_serializers/pull/971) Restore has_one to generator (@bf4)
+- [#965](https://github.com/rails-api/active_model_serializers/pull/965) options fedault valueserializable_hash and as_json (@bf4)
+- [#959](https://github.com/rails-api/active_model_serializers/pull/959) TYPO on README.md (@kangkyu)
+
+### [v0.10.0.rc2 (2015-06-16)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc1...v0.10.0.rc2)
+- [#958](https://github.com/rails-api/active_model_serializers/pull/958) Splitting json adapter into two (@joaomdmoura)
+ * adds FlattenJSON as default adapter
+- [#953](https://github.com/rails-api/active_model_serializers/pull/953) use model name to determine the type (@lsylvester)
+ * uses model name to determine the type
+- [#949](https://github.com/rails-api/active_model_serializers/pull/949) Don't pass serializer option to associated serializers (@bf4, @edwardloveall)
+- [#902](https://github.com/rails-api/active_model_serializers/pull/902) Added serializer file digest to the cache_key (@cristianbica)
+- [#948](https://github.com/rails-api/active_model_serializers/pull/948) AMS supports JSONAPI 1.0 instead of RC4 (@SeyZ)
+- [#936](https://github.com/rails-api/active_model_serializers/pull/936) Include meta when using json adapter with custom root (@chrisbranson)
+- [#942](https://github.com/rails-api/active_model_serializers/pull/942) Small code styling issue (@thiagofm)
+- [#930](https://github.com/rails-api/active_model_serializers/pull/930) Reverting PR #909 (@joaomdmoura)
+- [#924](https://github.com/rails-api/active_model_serializers/pull/924) Avoid unecessary calls to attribute methods when fragment caching (@navinpeiris)
+- [#925](https://github.com/rails-api/active_model_serializers/pull/925) Updates JSON API Adapter to generate RC4 schema (@benedikt)
+ * adds JSON API support 1.0
+- [#918](https://github.com/rails-api/active_model_serializers/pull/918) Adding rescue_with_handler to clear state (@ryansch)
+- [#909](https://github.com/rails-api/active_model_serializers/pull/909) Defining Json-API Adapter as Default (@joaomdmoura)
+ * remove root key option and split JSON adapter
+- [#914](https://github.com/rails-api/active_model_serializers/pull/914) Prevent possible duplicated attributes in serializer (@groyoh)
+- [#880](https://github.com/rails-api/active_model_serializers/pull/880) Inabling subclasses serializers to inherit attributes (@groyoh)
+- [#913](https://github.com/rails-api/active_model_serializers/pull/913) Avoiding the serializer option when instantiating a new one for ArraySerializer Fixed #911 (@groyoh)
+- [#897](https://github.com/rails-api/active_model_serializers/pull/897) Allow to define custom serializer for given class (@imanel)
+- [#892](https://github.com/rails-api/active_model_serializers/pull/892) Fixed a bug that appeared when json adapter serialize a nil association (@groyoh)
+- [#895](https://github.com/rails-api/active_model_serializers/pull/895) Adding a test to cover 'meta' and 'meta_key' attr_readers (@adomokos)
+- [#894](https://github.com/rails-api/active_model_serializers/pull/894) Fixing typos in README.md (@adomokos)
+- [#888](https://github.com/rails-api/active_model_serializers/pull/888) Changed duplicated test name in action controller test (@groyoh)
+- [#890](https://github.com/rails-api/active_model_serializers/pull/890) Remove unused method `def_serializer` (@JustinAiken)
+- [#887](https://github.com/rails-api/active_model_serializers/pull/887) Fixing tests on JRuby (@joaomdmoura)
+- [#885](https://github.com/rails-api/active_model_serializers/pull/885) Updates rails versions for test and dev (@tonyta)
+
+### [v0.10.0.rc1 (2015-04-22)](https://github.com/rails-api/active_model_serializers/compare/86fc7d7227f3ce538fcb28c1e8c7069ce311f0e1...v0.10.0.rc1)
+- [#810](https://github.com/rails-api/active_model_serializers/pull/810) Adding Fragment Cache to AMS (@joaomdmoura)
+ * adds fragment cache support
+- [#868](https://github.com/rails-api/active_model_serializers/pull/868) Fixed a bug that appears when a nil association is included (@groyoh)
+- [#861](https://github.com/rails-api/active_model_serializers/pull/861) README: Add emphasis to single-word difference (@machty)
+- [#858](https://github.com/rails-api/active_model_serializers/pull/858) Included resource fixes (@mateomurphy)
+- [#853](https://github.com/rails-api/active_model_serializers/pull/853) RC3 Updates for JSON API (@mateomurphy)
+- [#852](https://github.com/rails-api/active_model_serializers/pull/852) Fix options merge order in `each_association` (@mateomurphy)
+- [#850](https://github.com/rails-api/active_model_serializers/pull/850) Use association value for determining serializer used (@mateomurphy)
+- [#843](https://github.com/rails-api/active_model_serializers/pull/843) Remove the mailing list from the README (@JoshSmith)
+- [#842](https://github.com/rails-api/active_model_serializers/pull/842) Add notes on how you can help to contributing documentation (@JoshSmith)
+- [#833](https://github.com/rails-api/active_model_serializers/pull/833) Cache serializers for class (@lsylvester)
+- [#837](https://github.com/rails-api/active_model_serializers/pull/837) Store options in array serializers (@kurko)
+- [#836](https://github.com/rails-api/active_model_serializers/pull/836) Makes passed in options accessible inside serializers (@kurko)
+- [#773](https://github.com/rails-api/active_model_serializers/pull/773) Make json api adapter 'include' option accept an array (@sweatypitts)
+- [#830](https://github.com/rails-api/active_model_serializers/pull/830) Add contributing readme (@JoshSmith)
+- [#811](https://github.com/rails-api/active_model_serializers/pull/811) Reimplement serialization scope and scope_name (@mateomurphy)
+- [#725](https://github.com/rails-api/active_model_serializers/pull/725) Support has_one to be compatible with 0.8.x (@ggordon)
+ * adds `has_one` attribute for backwards compatibility
+- [#822](https://github.com/rails-api/active_model_serializers/pull/822) Replace has_one with attribute in template (@bf4)
+- [#821](https://github.com/rails-api/active_model_serializers/pull/821) Fix explicit serializer for associations (@wjordan)
+- [#798](https://github.com/rails-api/active_model_serializers/pull/798) Fix lost test `test_include_multiple_posts_and_linked` (@donbobka)
+- [#807](https://github.com/rails-api/active_model_serializers/pull/807) Add Overriding attribute methods section to README. (@alexstophel)
+- [#693](https://github.com/rails-api/active_model_serializers/pull/693) Cache Support at AMS 0.10.0 (@joaomdmoura)
+ * adds cache support to attributes and associations.
+- [#792](https://github.com/rails-api/active_model_serializers/pull/792) Association overrides (@kurko)
+ * adds method to override association
+- [#794](https://github.com/rails-api/active_model_serializers/pull/794) add to_param for correct URL generation (@carlesjove)
+
+### v0.10.0-pre
+
+- [Introduce Adapter](https://github.com/rails-api/active_model_serializers/commit/f00fe5595ddf741dc26127ed8fe81adad833ead5)
+- Prefer `ActiveModel::Serializer` to `ActiveModelSerializers`:
+ - [Namespace](https://github.com/rails-api/active_model_serializers/commit/729a823868e8c7ac86c653fcc7100ee511e08cb6#diff-fe7aa2941c19a41ccea6e52940d84016).
+ - [README](https://github.com/rails-api/active_model_serializers/commit/4a2d9853ba7486acc1747752982aa5650e7fd6e9).
diff --git a/CHANGELOG-prehistory.md b/CHANGELOG-prehistory.md
new file mode 100644
index 00000000..a2758830
--- /dev/null
+++ b/CHANGELOG-prehistory.md
@@ -0,0 +1,15 @@
+## Prehistory
+
+- [Changing Serialization/Serializers namespace to `Serializable` (November 30, 2011)](https://github.com/rails/rails/commit/8896b4fdc8a543157cdf4dfc378607ebf6c10ab0)
+ - [Merge branch 'serializers'. This implements the ActiveModel::Serializer object. Includes code, tests, generators and guides. From José and Yehuda with love.](https://github.com/rails/rails/commit/fcacc6986ab60f1fb2e423a73bf47c7abd7b191d)
+ - But [was reverted](https://github.com/rails/rails/commit/5b2eb64ceb08cd005dc06b721935de5853971473).
+ '[Revert the serializers API as other alternatives are now also under discussion](https://github.com/rails/rails/commit/0a4035b12a6c59253cb60f9e3456513c6a6a9d33)'.
+- [Proposed Implementation to Rails 3.2 by @wycats and @josevalim (November 25, 2011)](https://github.com/rails/rails/pull/3753)
+ - [Creation of `ActionController::Serialization`, initial serializer
+ support (September, 26 2011)](https://github.com/rails/rails/commit/8ff7693a8dc61f43fc4eaf72ed24d3b8699191fe).
+ - [Docs and CHANGELOG](https://github.com/rails/rails/commit/696d01f7f4a8ed787924a41cce6df836cd73c46f)
+ - [Deprecation of ActiveModel::Serialization to ActiveModel::Serializable](https://github.com/rails/rails/blob/696d01f7f4a8ed787924a41cce6df836cd73c46f/activemodel/lib/active_model/serialization.rb)
+- [Creation of `ActiveModel::Serialization` from `ActiveModel::Serializer` in Rails (2009)](https://github.com/rails/rails/commit/c6bc8e662614be711f45a8d4b231d5f993b024a7#diff-d029b9768d8df0407a35804a468e3ae5)
+- [Integration of `ActiveModel::Serializer` into `ActiveRecord::Serialization`](https://github.com/rails/rails/commit/783db25e0c640c1588732967a87d65c10fddc08e)
+- [Creation of `ActiveModel::Serializer` in Rails (2009)](https://github.com/rails/rails/commit/d2b78b3594b9cc9870e6a6ebfeb2e56d00e6ddb8#diff-80d5beeced9bdc24ca2b04a201543bdd)
+- [Creation of `ActiveModel::Serializers::JSON` in Rails (2009)](https://github.com/rails/rails/commit/fbdf706fffbfb17731a1f459203d242414ef5086)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c975e473..11070ef7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,6 @@
-## 0.10.x
+## Dev
-### [master (unreleased)](https://github.com/rails-api/active_model_serializers/compare/v0.10.6...master)
+### [master (unreleased)](https://github.com/rails-api/active_model_serializers/compare/master..dev)
Breaking changes:
@@ -10,641 +10,10 @@ Fixes:
Misc:
-### [v0.10.6 (2017-05-01)](https://github.com/rails-api/active_model_serializers/compare/v0.10.5...v0.10.6)
+## [0.10.x](CHANGELOG-0-10.md)
-Fixes:
+## [0.09.x](CHANGELOG-0-09.md)
-- [#1857](https://github.com/rails-api/active_model_serializers/pull/1857) JSON:API does not load belongs_to relation to get identifier id. (@bf4)
-- [#2119](https://github.com/rails-api/active_model_serializers/pull/2119) JSON:API returns null resource object identifier when 'id' is null. (@bf4)
-- [#2093](https://github.com/rails-api/active_model_serializers/pull/2093) undef problematic Serializer methods: display, select. (@bf4)
+## [0.08.x](CHANGELOG-0-08.md)
-Misc:
-
-- [#2104](https://github.com/rails-api/active_model_serializers/pull/2104) Documentation for serializers and rendering. (@cassidycodes)
-- [#2081](https://github.com/rails-api/active_model_serializers/pull/2081) Documentation for `include` option in adapters. (@charlie-wasp)
-- [#2120](https://github.com/rails-api/active_model_serializers/pull/2120) Documentation for association options: foreign_key, type, class_name, namespace. (@bf4)
-
-### [v0.10.5 (2017-03-07)](https://github.com/rails-api/active_model_serializers/compare/v0.10.4...v0.10.5)
-
-Breaking changes:
-
-Features:
-
-- [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) ActiveModelSerializers::Model#attributes. Originally in [#1982](https://github.com/rails-api/active_model_serializers/pull/1982). (@bf4)
-- [#2057](https://github.com/rails-api/active_model_serializers/pull/2057)
- Update version constraint for jsonapi-renderer to `['>= 0.1.1.beta1', '< 0.2']`
- (@jaredbeck)
-
-Fixes:
-
-- [#2022](https://github.com/rails-api/active_model_serializers/pull/2022) Mutation of ActiveModelSerializers::Model now changes the attributes. Originally in [#1984](https://github.com/rails-api/active_model_serializers/pull/1984). (@bf4)
-
-Misc:
-
-- [#2055](https://github.com/rails-api/active_model_serializers/pull/2055)
- Replace deprecated dependency jsonapi with jsonapi-renderer. (@jaredbeck)
-- [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) Make test attributes explicit. Tests have Model#associations. (@bf4)
-- [#1981](https://github.com/rails-api/active_model_serializers/pull/1981) Fix relationship link documentation. (@groyoh)
-- [#2035](https://github.com/rails-api/active_model_serializers/pull/2035) Document how to disable the logger. (@MSathieu)
-- [#2039](https://github.com/rails-api/active_model_serializers/pull/2039) Documentation fixes. (@biow0lf)
-
-### [v0.10.4 (2017-01-06)](https://github.com/rails-api/active_model_serializers/compare/v0.10.3...v0.10.4)
-
-Misc:
-
-- [#2005](https://github.com/rails-api/active_model_serializers/pull/2005) Update jsonapi runtime dependency to 0.1.1.beta6, support Ruby 2.4. (@kofronpi)
-- [#1993](https://github.com/rails-api/active_model_serializers/pull/1993) Swap out KeyTransform for CaseTransform gem for the possibility of native extension use. (@NullVoxPopuli)
-
-### [v0.10.3 (2016-11-21)](https://github.com/rails-api/active_model_serializers/compare/v0.10.2...v0.10.3)
-
-Fixes:
-
-- [#1973](https://github.com/rails-api/active_model_serializers/pull/1973) Fix namespace lookup for collections and has_many relationships (@groyoh)
-- [#1887](https://github.com/rails-api/active_model_serializers/pull/1887) Make the comment reflect what the function does (@johnnymo87)
-- [#1890](https://github.com/rails-api/active_model_serializers/issues/1890) Ensure generator inherits from ApplicationSerializer when available (@richmolj)
-- [#1922](https://github.com/rails-api/active_model_serializers/pull/1922) Make railtie an optional dependency in runtime (@ggpasqualino)
-- [#1930](https://github.com/rails-api/active_model_serializers/pull/1930) Ensure valid jsonapi when relationship has no links or data (@richmolj)
-
-Features:
-
-- [#1757](https://github.com/rails-api/active_model_serializers/pull/1757) Make serializer lookup chain configurable. (@NullVoxPopuli)
-- [#1968](https://github.com/rails-api/active_model_serializers/pull/1968) (@NullVoxPopuli)
- - Add controller namespace to default controller lookup
- - Provide a `namespace` render option
- - document how set the namespace in the controller for implicit lookup.
-- [#1791](https://github.com/rails-api/active_model_serializers/pull/1791) (@bf4, @youroff, @NullVoxPopuli)
- - Added `jsonapi_namespace_separator` config option.
-- [#1889](https://github.com/rails-api/active_model_serializers/pull/1889) Support key transformation for Attributes adapter (@iancanderson, @danbee)
-- [#1917](https://github.com/rails-api/active_model_serializers/pull/1917) Add `jsonapi_pagination_links_enabled` configuration option (@richmolj)
-- [#1797](https://github.com/rails-api/active_model_serializers/pull/1797) Only include 'relationships' when sideloading (@richmolj)
-
-Fixes:
-
-- [#1833](https://github.com/rails-api/active_model_serializers/pull/1833) Remove relationship links if they are null (@groyoh)
-- [#1881](https://github.com/rails-api/active_model_serializers/pull/1881) ActiveModelSerializers::Model correctly works with string keys (@yevhene)
-
-Misc:
-- [#1767](https://github.com/rails-api/active_model_serializers/pull/1767) Replace raising/rescuing `CollectionSerializer::NoSerializerError`,
- throw/catch `:no_serializer`. (@bf4)
-- [#1839](https://github.com/rails-api/active_model_serializers/pull/1839) `fields` tests demonstrating usage for both attributes and relationships. (@NullVoxPopuli)
-- [#1812](https://github.com/rails-api/active_model_serializers/pull/1812) add a code of conduct (@corainchicago)
-
-- [#1878](https://github.com/rails-api/active_model_serializers/pull/1878) Cache key generation for serializers now uses `ActiveSupport::Cache.expand_cache_key` instead of `Array#join` by default and is also overridable. This change should be backward-compatible. (@markiz)
-
-- [#1799](https://github.com/rails-api/active_model_serializers/pull/1799) Add documentation for setting the adapter. (@cassidycodes)
-- [#1909](https://github.com/rails-api/active_model_serializers/pull/1909) Add documentation for relationship links. (@vasilakisfil, @NullVoxPopuli)
-- [#1959](https://github.com/rails-api/active_model_serializers/pull/1959) Add documentation for root. (@shunsuke227ono)
-- [#1967](https://github.com/rails-api/active_model_serializers/pull/1967) Improve type method documentation. (@yukideluxe)
-
-### [v0.10.2 (2016-07-05)](https://github.com/rails-api/active_model_serializers/compare/v0.10.1...v0.10.2)
-
-Fixes:
-- [#1814](https://github.com/rails-api/active_model_serializers/pull/1814) Ensuring read_multi works with fragment cache
-- [#1848](https://github.com/rails-api/active_model_serializers/pull/1848) Redefine associations on inherited serializers. (@EhsanYousefi)
-
-Misc:
-- [#1808](https://github.com/rails-api/active_model_serializers/pull/1808) Adds documentation for `fields` option. (@luizkowalski)
-
-### [v0.10.1 (2016-06-16)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0...v0.10.1)
-
-Features:
-- [#1668](https://github.com/rails-api/active_model_serializers/pull/1668) Exclude nil and empty links. (@sigmike)
-- [#1426](https://github.com/rails-api/active_model_serializers/pull/1426) Add ActiveModelSerializers.config.default_includes (@empact)
-
-Fixes:
-- [#1754](https://github.com/rails-api/active_model_serializers/pull/1754) Fixes #1759, Grape integration, improves serialization_context
- missing error message on pagination. Document overriding CollectionSerializer#paginated?. (@bf4)
- Moved serialization_context creation to Grape formatter, so resource serialization works without explicit calls to the `render` helper method.
- Added Grape collection tests. (@onomated)
-- [#1287](https://github.com/rails-api/active_model_serializers/pull/1287) Pass `fields` options from adapter to serializer. (@vasilakisfil)
-- [#1710](https://github.com/rails-api/active_model_serializers/pull/1710) Prevent association loading when `include_data` option
- is set to `false`. (@groyoh)
-- [#1747](https://github.com/rails-api/active_model_serializers/pull/1747) Improve jsonapi mime type registration for Rails 5 (@remear)
-
-Misc:
-- [#1734](https://github.com/rails-api/active_model_serializers/pull/1734) Adds documentation for conditional attribute (@lambda2)
-- [#1685](https://github.com/rails-api/active_model_serializers/pull/1685) Replace `IncludeTree` with `IncludeDirective` from the jsonapi gem.
-
-### [v0.10.0 (2016-05-17)](https://github.com/rails-api/active_model_serializers/compare/4a2d9853ba7...v0.10.0)
-
-Breaking changes:
-- [#1662](https://github.com/rails-api/active_model_serializers/pull/1662) Drop support for Rails 4.0 and Ruby 2.0.0. (@remear)
-
-Features:
-- [#1677](https://github.com/rails-api/active_model_serializers/pull/1677) Add `assert_schema`, `assert_request_schema`, `assert_request_response_schema`. (@bf4)
-- [#1697](https://github.com/rails-api/active_model_serializers/pull/1697) Include actual exception message with custom exceptions;
- `Test::Schema` exceptions are now `Minitest::Assertion`s. (@bf4)
-- [#1699](https://github.com/rails-api/active_model_serializers/pull/1699) String/Lambda support for conditional attributes/associations (@mtsmfm)
-- [#1687](https://github.com/rails-api/active_model_serializers/pull/1687) Only calculate `_cache_digest` (in `cache_key`) when `skip_digest` is false. (@bf4)
-- [#1647](https://github.com/rails-api/active_model_serializers/pull/1647) Restrict usage of `serializable_hash` options
- to the ActiveModel::Serialization and ActiveModel::Serializers::JSON interface. (@bf4)
-
-Fixes:
-- [#1700](https://github.com/rails-api/active_model_serializers/pull/1700) Support pagination link for Kaminari when no data is returned. (@iamnader)
-- [#1726](https://github.com/rails-api/active_model_serializers/pull/1726) Adds polymorphic option to association definition which includes association type/nesting in serializer (@cgmckeever)
-
-Misc:
-- [#1673](https://github.com/rails-api/active_model_serializers/pull/1673) Adds "How to" guide on using AMS with POROs (@DrSayre)
-- [#1730](https://github.com/rails-api/active_model_serializers/pull/1730) Adds documentation for overriding default serializer based on conditions (@groyoh/@cgmckeever)
-
-### [v0.10.0.rc5 (2016-04-04)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc4...v0.10.0.rc5)
-
-Breaking changes:
-
-- [#1645](https://github.com/rails-api/active_model_serializers/pull/1645) Changed :dashed key transform to :dash. (@remear)
-- [#1574](https://github.com/rails-api/active_model_serializers/pull/1574) Default key case for the JsonApi adapter changed to dashed. (@remear)
-
-Features:
-- [#1645](https://github.com/rails-api/active_model_serializers/pull/1645) Transform keys referenced in values. (@remear)
-- [#1650](https://github.com/rails-api/active_model_serializers/pull/1650) Fix serialization scope options `scope`, `scope_name`
- take precedence over `serialization_scope` in the controller.
- Fix tests that required tearing down dynamic methods. (@bf4)
-- [#1644](https://github.com/rails-api/active_model_serializers/pull/1644) Include adapter name in cache key so
- that the same serializer can be cached per adapter. (@bf4 via #1346 by @kevintyll)
-- [#1642](https://github.com/rails-api/active_model_serializers/pull/1642) Prefer object.cache_key over the generated
- cache key. (@bf4 via #1346 by @kevintyll)
-- [#1637](https://github.com/rails-api/active_model_serializers/pull/1637) Make references to 'ActionController::Base.cache_store' explicit
- in order to avoid issues when application controllers inherit from 'ActionController::API'. (@ncuesta)
-- [#1633](https://github.com/rails-api/active_model_serializers/pull/1633) Yield 'serializer' to serializer association blocks. (@bf4)
-- [#1616](https://github.com/rails-api/active_model_serializers/pull/1616) SerializableResource handles no serializer like controller. (@bf4)
-- [#1618](https://github.com/rails-api/active_model_serializers/issues/1618) Get collection root key for
- empty collection from explicit serializer option, when possible. (@bf4)
-- [#1574](https://github.com/rails-api/active_model_serializers/pull/1574) Provide key translation. (@remear)
-- [#1494](https://github.com/rails-api/active_model_serializers/pull/1494) Make serializers serializalbe
- (using the Attributes adapter by default). (@bf4)
-- [#1550](https://github.com/rails-api/active_model_serializers/pull/1550) Add
- Rails url_helpers to `SerializationContext` for use in links. (@remear, @bf4)
-- [#1004](https://github.com/rails-api/active_model_serializers/pull/1004) JSON API errors object implementation.
- - Only implements `detail` and `source` as derived from `ActiveModel::Error`
- - Provides checklist of remaining questions and remaining parts of the spec.
-- [#1515](https://github.com/rails-api/active_model_serializers/pull/1515) Adds support for symbols to the
- `ActiveModel::Serializer.type` method. (@groyoh)
-- [#1504](https://github.com/rails-api/active_model_serializers/pull/1504) Adds the changes missing from #1454
- and add more tests for resource identifier and relationship objects. Fix association block with link
- returning `data: nil`.(@groyoh)
-- [#1372](https://github.com/rails-api/active_model_serializers/pull/1372) Support
- cache_store.read_multi. (@LcpMarvel)
-- [#1018](https://github.com/rails-api/active_model_serializers/pull/1018) Add more tests and docs for top-level links. (@leandrocp)
-- [#1454](https://github.com/rails-api/active_model_serializers/pull/1454) Add support for
- relationship-level links and meta attributes. (@beauby)
-- [#1340](https://github.com/rails-api/active_model_serializers/pull/1340) Add support for resource-level meta. (@beauby)
-
-Fixes:
-- [#1657](https://github.com/rails-api/active_model_serializers/pull/1657) Add missing missing require "active_support/json". (@andreaseger)
-- [#1661](https://github.com/rails-api/active_model_serializers/pull/1661) Fixes `read_attribute_for_serialization` not
- seeing methods defined in serialization superclass (#1653, #1658, #1660), introduced in #1650. (@bf4)
-- [#1651](https://github.com/rails-api/active_model_serializers/pull/1651) Fix deserialization of nil relationships. (@NullVoxPopuli)
-- [#1480](https://github.com/rails-api/active_model_serializers/pull/1480) Fix setting of cache_store from Rails configuration. (@bf4)
- Fix unintentional mutating of value in memory cache store. (@groyoh)
-- [#1622](https://github.com/rails-api/active_model_serializers/pull/1622) Fragment cache changed from per-record to per-serializer.
- Now, two serializers that use the same model may be separately cached. (@lserman)
-- [#1478](https://github.com/rails-api/active_model_serializers/pull/1478) Cache store will now be correctly set when serializers are
- loaded *before* Rails initializes. (@bf4)
-- [#1570](https://github.com/rails-api/active_model_serializers/pull/1570) Fixed pagination issue with last page size. (@bmorrall)
-- [#1516](https://github.com/rails-api/active_model_serializers/pull/1516) No longer return a nil href when only
- adding meta to a relationship link. (@groyoh)
-- [#1458](https://github.com/rails-api/active_model_serializers/pull/1458) Preserve the serializer
- type when fragment caching. (@bdmac)
-- [#1477](https://github.com/rails-api/active_model_serializers/pull/1477) Fix `fragment_cached?`
- method to check if caching. (@bdmac)
-- [#1501](https://github.com/rails-api/active_model_serializers/pull/1501) Adds tests for SerializableResource::use_adapter?,doc typos (@domitian)
-- [#1488](https://github.com/rails-api/active_model_serializers/pull/1488) Require ActiveSupport's string inflections (@nate00)
-
-Misc:
-- [#1608](https://github.com/rails-api/active_model_serializers/pull/1608) Move SerializableResource to ActiveModelSerializers (@groyoh)
-- [#1602](https://github.com/rails-api/active_model_serializers/pull/1602) Add output examples to Adapters docs (@remear)
-- [#1557](https://github.com/rails-api/active_model_serializers/pull/1557) Update docs regarding overriding the root key (@Jwan622)
-- [#1471](https://github.com/rails-api/active_model_serializers/pull/1471) [Cleanup] Serializer caching is its own concern. (@bf4)
-- [#1482](https://github.com/rails-api/active_model_serializers/pull/1482) Document JSON API implementation defs and progress in class. (@bf4)
-- [#1551](https://github.com/rails-api/active_model_serializers/pull/1551) Added codebeat badge (@korzonek)
-- [#1527](https://github.com/rails-api/active_model_serializers/pull/1527) Refactor fragment cache class. (@groyoh)
-- [#1560](https://github.com/rails-api/active_model_serializers/pull/1560) Update rubocop and address its warnings. (@bf4 @groyoh)
-- [#1545](https://github.com/rails-api/active_model_serializers/pull/1545) Document how to pass arbitrary options to the
- serializer (@CodedBeardedSignedTaylor)
-- [#1496](https://github.com/rails-api/active_model_serializers/pull/1496) Run all branches against JRuby on CI (@nadavshatz)
-- [#1559](https://github.com/rails-api/active_model_serializers/pull/1559) Add a deprecation DSL. (@bf4 @groyoh)
-- [#1543](https://github.com/rails-api/active_model_serializers/pull/1543) Add the changes missing from #1535. (@groyoh)
-- [#1535](https://github.com/rails-api/active_model_serializers/pull/1535) Move the adapter and adapter folder to
- active_model_serializers folder and changes the module namespace. (@domitian @bf4)
-- [#1497](https://github.com/rails-api/active_model_serializers/pull/1497) Add JRuby-9000 to appveyor.yml(@corainchicago)
-- [#1420](https://github.com/rails-api/active_model_serializers/pull/1420) Adds tests and documentation for polymorphism(@marcgarreau)
-
-
-### [v0.10.0.rc4 (2016-01-27)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc3...v0.10.0.rc4)
-Breaking changes:
-
-- [#1360](https://github.com/rails-api/active_model_serializers/pull/1360)
- [#1369](https://github.com/rails-api/active_model_serializers/pull/1369) Drop support for Ruby 1.9.3 (@karaAJC, @maurogeorge)
-- [#1131](https://github.com/rails-api/active_model_serializers/pull/1131) Remove Serializer#root_name (@beauby)
-- [#1138](https://github.com/rails-api/active_model_serializers/pull/1138) Introduce Adapter::Base (@bf4)
- * Adapters now inherit Adapter::Base. 'Adapter' is now a module, no longer a class.
- * using a class as a namespace that you also inherit from is complicated and circular at times i.e.
- buggy (see https://github.com/rails-api/active_model_serializers/pull/1177)
- * The class methods on Adapter aren't necessarily related to the instance methods, they're more
- Adapter functions.
- * named `Base` because it's a Rails-ism.
- * It helps to isolate and highlight what the Adapter interface actually is.
-- [#1418](https://github.com/rails-api/active_model_serializers/pull/1418)
- serialized collections now use the root option as is; now, only the
- root derived from the serializer or object is always pluralized.
-
-Features:
-
-- [#1406](https://github.com/rails-api/active_model_serializers/pull/1406) Allow for custom dynamic values in JSON API links (@beauby)
-- [#1270](https://github.com/rails-api/active_model_serializers/pull/1270) Adds `assert_response_schema` test helper (@maurogeorge)
-- [#1099](https://github.com/rails-api/active_model_serializers/pull/1099) Adds `assert_serializer` test helper (@maurogeorge)
-- [#1403](https://github.com/rails-api/active_model_serializers/pull/1403) Add support for if/unless on attributes/associations (@beauby)
-- [#1248](https://github.com/rails-api/active_model_serializers/pull/1248) Experimental: Add support for JSON API deserialization (@beauby)
-- [#1378](https://github.com/rails-api/active_model_serializers/pull/1378) Change association blocks
- to be evaluated in *serializer* scope, rather than *association* scope. (@bf4)
- * Syntax changes from e.g.
- `has_many :titles do customers.pluck(:title) end` (in #1356) to
- `has_many :titles do object.customers.pluck(:title) end`
-- [#1356](https://github.com/rails-api/active_model_serializers/pull/1356) Add inline syntax for
- attributes and associations (@bf4 @beauby @noahsilas)
- * Allows defining attributes so that they don't conflict with existing methods. e.g. `attribute
- :title do 'Mr. Topum Hat' end`
- * Allows defining associations so that they don't conflict with existing methods. e.g. `has_many
- :titles do customers.pluck(:title) end`
- * Allows dynamic associations, as compared to compare to using
- [`virtual_value`](https://github.com/rails-api/active_model_serializers/pull/1356#discussion_r47146466).
- e.g. `has_many :reviews, virtual_value: [{ id: 1 }, { id: 2 }]`
- * Removes dynamically defined methods on the serializer
-- [#1336](https://github.com/rails-api/active_model_serializers/pull/1336) Added support for Grape >= 0.13, < 1.0 (@johnhamelink)
-- [#1322](https://github.com/rails-api/active_model_serializers/pull/1322) Instrumenting rendering of resources (@bf4, @maurogeorge)
-- [#1291](https://github.com/rails-api/active_model_serializers/pull/1291) Add logging (@maurogeorge)
-- [#1272](https://github.com/rails-api/active_model_serializers/pull/1272) Add PORO serializable base class: ActiveModelSerializers::Model (@bf4)
-- [#1255](https://github.com/rails-api/active_model_serializers/pull/1255) Make more class attributes inheritable (@bf4)
-- [#1249](https://github.com/rails-api/active_model_serializers/pull/1249) Inheritance of serializer inheriting the cache configuration(@Rodrigora)
-- [#1247](https://github.com/rails-api/active_model_serializers/pull/1247) Add support for toplevel JSON API links (@beauby)
-- [#1246](https://github.com/rails-api/active_model_serializers/pull/1246) Add support for resource-level JSON API links (@beauby)
-- [#1225](https://github.com/rails-api/active_model_serializers/pull/1225) Better serializer lookup, use nested serializer when it exists (@beauby)
-- [#1213](https://github.com/rails-api/active_model_serializers/pull/1213) `type` directive for serializer to control type field with json-api adapter (@youroff)
-- [#1172](https://github.com/rails-api/active_model_serializers/pull/1172) Better serializer registration, get more than just the first module (@bf4)
-- [#1158](https://github.com/rails-api/active_model_serializers/pull/1158) Add support for wildcards in `include` option (@beauby)
-- [#1127](https://github.com/rails-api/active_model_serializers/pull/1127) Add support for nested
- associations for JSON and Attributes adapters via the `include` option (@NullVoxPopuli, @beauby).
-- [#1050](https://github.com/rails-api/active_model_serializers/pull/1050) Add support for toplevel jsonapi member (@beauby, @bf4)
-- [#1251](https://github.com/rails-api/active_model_serializers/pull/1251) Rename ArraySerializer to
- CollectionSerializer for clarity, add ActiveModelSerializers.config.collection_serializer (@bf4)
-- [#1295](https://github.com/rails-api/active_model_serializers/pull/1295) Add config `serializer_lookup_enabled` that,
- when disabled, requires serializers to explicitly specified. (@trek)
-
-Fixes:
-
-- [#1352](https://github.com/rails-api/active_model_serializers/pull/1352) Fix generators; Isolate Rails-specifc code in Railties (@dgynn, @bf4)
-- [#1384](https://github.com/rails-api/active_model_serializers/pull/1384)Fix database state leaking across tests (@bf4)
-- [#1297](https://github.com/rails-api/active_model_serializers/pull/1297) Fix `fields` option to restrict relationships as well (@beauby)
-- [#1239](https://github.com/rails-api/active_model_serializers/pull/1239) Fix duplicates in JSON API compound documents (@beauby)
-- [#1214](https://github.com/rails-api/active_model_serializers/pull/1214) retrieve the key from the reflection options when building associations (@NullVoxPopuli, @hut8)
-- [#1358](https://github.com/rails-api/active_model_serializers/pull/1358) Handle serializer file paths with spaces (@rwstauner, @bf4)
-- [#1195](https://github.com/rails-api/active_model_serializers/pull/1195) Fix id override (@beauby)
-- [#1185](https://github.com/rails-api/active_model_serializers/pull/1185) Fix options passing in Json and Attributes adapters (@beauby)
-
-Misc:
-
-- [#1383](https://github.com/rails-api/active_model_serializers/pull/1383) Simplify reflections handling (@beauby)
-- [#1370](https://github.com/rails-api/active_model_serializers/pull/1370) Simplify attributes handling via a mixin (@beauby)
-- [#1301](https://github.com/rails-api/active_model_serializers/pull/1301) Mapping JSON API spec / schema to AMS (@bf4)
-- [#1271](https://github.com/rails-api/active_model_serializers/pull/1271) Handle no serializer source file to digest (@bf4)
-- [#1260](https://github.com/rails-api/active_model_serializers/pull/1260) Serialization and Cache Documentation (@bf4)
-- [#1259](https://github.com/rails-api/active_model_serializers/pull/1259) Add more info to CONTRIBUTING (@bf4)
-- [#1233](https://github.com/rails-api/active_model_serializers/pull/1233) Top-level meta and meta_key options no longer handled at serializer level (@beauby)
-- [#1232](https://github.com/rails-api/active_model_serializers/pull/1232) fields option no longer handled at serializer level (@beauby)
-- [#1220](https://github.com/rails-api/active_model_serializers/pull/1220) Remove empty rubocop.rake (@maurogeorge)
-- [#1178](https://github.com/rails-api/active_model_serializers/pull/1178) env CAPTURE_STDERR=false lets devs see hard failures (@bf4)
-- [#1177](https://github.com/rails-api/active_model_serializers/pull/1177) Remove Adapter autoloads in favor of require (@bf4)
-- [#1117](https://github.com/rails-api/active_model_serializers/pull/1117) FlattenJson adapter no longer inherits Json adapter, renamed to Attributes (@bf4)
-- [#1171](https://github.com/rails-api/active_model_serializers/pull/1171) add require statements to top of file (@shicholas)
-- [#1167](https://github.com/rails-api/active_model_serializers/pull/1167) Delegate Serializer.attributes to Serializer.attribute (@bf4)
-- [#1174](https://github.com/rails-api/active_model_serializers/pull/1174) Consistently refer to the 'JSON API' and the 'JsonApi' adapter (@bf4)
-- [#1173](https://github.com/rails-api/active_model_serializers/pull/1173) Comment private accessor warnings (@bf4)
-- [#1166](https://github.com/rails-api/active_model_serializers/pull/1166) Prefer methods over instance variables (@bf4)
-- [#1168](https://github.com/rails-api/active_model_serializers/pull/1168) Fix appveyor failure cache not being expired (@bf4)
-- [#1161](https://github.com/rails-api/active_model_serializers/pull/1161) Remove duplicate test helper (@bf4)
-- [#1360](https://github.com/rails-api/active_model_serializers/pull/1360) Update CI to test 2.2.2 -> 2.2.3 (@karaAJC)
-- [#1371](https://github.com/rails-api/active_model_serializers/pull/1371) Refactor, update, create documentation (@bf4)
-
-### [v0.10.0.rc3 (2015-09-16)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc2...v0.10.0.rc3)
-- [#1129](https://github.com/rails-api/active_model_serializers/pull/1129) Remove SerializableResource.serialize in favor of `.new` (@bf4)
-- [#1155](https://github.com/rails-api/active_model_serializers/pull/1155) Outside controller use tutorial (@CodedBeardedSignedTaylor)
-- [#1154](https://github.com/rails-api/active_model_serializers/pull/1154) Rubocop fixes for issues introduced by #1089 (@NullVoxPopuli)
-- [#1089](https://github.com/rails-api/active_model_serializers/pull/1089) Add ActiveModelSerializers.logger with default null device (@bf4)
-- [#1109](https://github.com/rails-api/active_model_serializers/pull/1109) Make better use of Minitest's lifecycle (@bf4)
-- [#1144](https://github.com/rails-api/active_model_serializers/pull/1144) Fix Markdown to adapters documentation (@bacarini)
-- [#1121](https://github.com/rails-api/active_model_serializers/pull/1121) Refactor `add_links` in JSONAPI adapter. (@beauby)
-- [#1150](https://github.com/rails-api/active_model_serializers/pull/1150) Remove legacy method accidentally reintroduced in #1017 (@beauby)
-- [#1149](https://github.com/rails-api/active_model_serializers/pull/1149) Update README with nested included association example. (@mattmueller)
-- [#1110](https://github.com/rails-api/active_model_serializers/pull/1110) Add lint tests for AR models (@beauby)
-- [#1131](https://github.com/rails-api/active_model_serializers/pull/1131) Extended format for JSONAPI `include` option (@beauby)
- * adds extended format for `include` option to JsonApi adapter
-- [#1142](https://github.com/rails-api/active_model_serializers/pull/1142) Updating wording on cache expiry in README (@leighhalliday)
-- [#1140](https://github.com/rails-api/active_model_serializers/pull/1140) Fix typo in fieldset exception (@lautis)
-- [#1132](https://github.com/rails-api/active_model_serializers/pull/1132) Get rid of unnecessary instance variables, and implied dependencies. (@beauby)
-- [#1139](https://github.com/rails-api/active_model_serializers/pull/1139) Documentation for serializing resources without render (@PericlesTheo)
-- [#1017](https://github.com/rails-api/active_model_serializers/pull/1017) Make Adapters registerable so they are not namespace-constrained (@bf4)
-- [#1120](https://github.com/rails-api/active_model_serializers/pull/1120) Add windows platform to loading sqlite3 (@Eric-Guo)
-- [#1123](https://github.com/rails-api/active_model_serializers/pull/1123) Remove url options (@bacarini)
-- [#1093](https://github.com/rails-api/active_model_serializers/pull/1093) Factor `with_adapter` + force cache clear before each test. (@beauby)
-- [#1095](https://github.com/rails-api/active_model_serializers/pull/1095) Add documentation about configuration options. (@beauby)
-- [#1069](https://github.com/rails-api/active_model_serializers/pull/1069) Add test coverage; account for no artifacts on CI (@bf4)
-- [#1103](https://github.com/rails-api/active_model_serializers/pull/1103) Move `id` and `json_api_type` methods from `Serializer` to `JsonApi`. (@beauby)
-- [#1106](https://github.com/rails-api/active_model_serializers/pull/1106) Add Style enforcer (via Rubocop) (@bf4)
-- [#1079](https://github.com/rails-api/active_model_serializers/pull/1079) Add ArraySerializer#object like Serializer (@bf4)
-- [#1096](https://github.com/rails-api/active_model_serializers/pull/1096) Fix definition of serializer attributes with multiple calls to `attri… (@beauby)
-- [#1105](https://github.com/rails-api/active_model_serializers/pull/1105) Add ActiveRecord-backed fixtures. (@beauby)
-- [#1108](https://github.com/rails-api/active_model_serializers/pull/1108) Better lint (@bf4)
-- [#1102](https://github.com/rails-api/active_model_serializers/pull/1102) Remove remains of `embed` option. (@beauby)
-- [#1090](https://github.com/rails-api/active_model_serializers/pull/1090) Clarify AMS dependencies (@bf4)
-- [#1081](https://github.com/rails-api/active_model_serializers/pull/1081) Add configuration option to set resource type to singular/plural (@beauby)
-- [#1067](https://github.com/rails-api/active_model_serializers/pull/1067) Fix warnings (@bf4)
-- [#1066](https://github.com/rails-api/active_model_serializers/pull/1066) Adding appveyor to the project (@joaomdmoura, @Eric-Guo, @bf4)
-- [#1071](https://github.com/rails-api/active_model_serializers/pull/1071) Make testing suite running and pass in Windows (@Eric-Guo, @bf4)
-- [#1041](https://github.com/rails-api/active_model_serializers/pull/1041) Adding pagination links (@bacarini)
- * adds support for `pagination links` at top level of JsonApi adapter
-- [#1063](https://github.com/rails-api/active_model_serializers/pull/1063) Lead by example: lint PORO model (@bf4)
-- [#1](https://github.com/rails-api/active_model_serializers/pull/1) Test caller line parsing and digesting (@bf4)
-- [#1048](https://github.com/rails-api/active_model_serializers/pull/1048) Let FlattenJson adapter decide it doesn't include meta (@bf4)
-- [#1060](https://github.com/rails-api/active_model_serializers/pull/1060) Update fragment cache to support namespaced objects (@aaronlerch)
-- [#1052](https://github.com/rails-api/active_model_serializers/pull/1052) Use underscored json_root when serializing a collection (@whatthewhat)
-- [#1051](https://github.com/rails-api/active_model_serializers/pull/1051) Fix some invalid JSON in docs (@tjschuck)
-- [#1049](https://github.com/rails-api/active_model_serializers/pull/1049) Fix incorrect s/options = {}/options ||= {} (@bf4)
-- [#1037](https://github.com/rails-api/active_model_serializers/pull/1037) allow for type attribute (@lanej)
-- [#1034](https://github.com/rails-api/active_model_serializers/pull/1034) allow id attribute to be overriden (@lanej)
-- [#1035](https://github.com/rails-api/active_model_serializers/pull/1035) Fixed Comments highlight (@artLopez)
-- [#1031](https://github.com/rails-api/active_model_serializers/pull/1031) Disallow to define multiple associations at once (@bolshakov)
-- [#1032](https://github.com/rails-api/active_model_serializers/pull/1032) Wrap railtie requirement with rescue (@elliotlarson)
-- [#1026](https://github.com/rails-api/active_model_serializers/pull/1026) Bump Version Number to 0.10.0.rc2 (@jfelchner)
-- [#985](https://github.com/rails-api/active_model_serializers/pull/985) Associations implementation refactoring (@bolshakov)
-- [#954](https://github.com/rails-api/active_model_serializers/pull/954) Encapsulate serialization in ActiveModel::SerializableResource (@bf4)
-- [#972](https://github.com/rails-api/active_model_serializers/pull/972) Capture app warnings on test run (@bf4)
-- [#1019](https://github.com/rails-api/active_model_serializers/pull/1019) Improve README.md (@baojjeu)
-- [#998](https://github.com/rails-api/active_model_serializers/pull/998) Changing root to model class name (@joaomdmoura)
-- [#1006](https://github.com/rails-api/active_model_serializers/pull/1006) Fix adapter inflection bug for api -> API (@bf4)
-- [#1016](https://github.com/rails-api/active_model_serializers/pull/1016) require rails/railtie before subclassing Rails::Railtie (@bf4)
-- [#1013](https://github.com/rails-api/active_model_serializers/pull/1013) Root option with empty array support (@vyrak, @mareczek)
-- [#994](https://github.com/rails-api/active_model_serializers/pull/994) Starting Docs structure (@joaomdmoura)
-- [#1007](https://github.com/rails-api/active_model_serializers/pull/1007) Bug fix for ArraySerializer json_key (@jiajiawang)
-- [#1003](https://github.com/rails-api/active_model_serializers/pull/1003) Fix transient test failures (@Rodrigora)
-- [#996](https://github.com/rails-api/active_model_serializers/pull/996) Add linter for serializable resource (@bf4)
-- [#990](https://github.com/rails-api/active_model_serializers/pull/990) Adding json-api meta test (@joaomdmoura)
-- [#984](https://github.com/rails-api/active_model_serializers/pull/984) Add option "key" to serializer associations (@Rodrigora)
-- [#982](https://github.com/rails-api/active_model_serializers/pull/982) Fix typo (@bf4)
-- [#981](https://github.com/rails-api/active_model_serializers/pull/981) Remove unused PORO#to_param (@bf4)
-- [#978](https://github.com/rails-api/active_model_serializers/pull/978) fix generators template bug (@regonn)
-- [#975](https://github.com/rails-api/active_model_serializers/pull/975) Fixes virtual value not being used (@GriffinHeart)
-- [#970](https://github.com/rails-api/active_model_serializers/pull/970) Fix transient tests failures (@Rodrigora)
-- [#962](https://github.com/rails-api/active_model_serializers/pull/962) Rendering objects that doesn't have serializers (@bf4, @joaomdmoura, @JustinAiken)
-- [#939](https://github.com/rails-api/active_model_serializers/pull/939) Use a more precise generated cache key (@aaronlerch)
-- [#971](https://github.com/rails-api/active_model_serializers/pull/971) Restore has_one to generator (@bf4)
-- [#965](https://github.com/rails-api/active_model_serializers/pull/965) options fedault valueserializable_hash and as_json (@bf4)
-- [#959](https://github.com/rails-api/active_model_serializers/pull/959) TYPO on README.md (@kangkyu)
-
-### [v0.10.0.rc2 (2015-06-16)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc1...v0.10.0.rc2)
-- [#958](https://github.com/rails-api/active_model_serializers/pull/958) Splitting json adapter into two (@joaomdmoura)
- * adds FlattenJSON as default adapter
-- [#953](https://github.com/rails-api/active_model_serializers/pull/953) use model name to determine the type (@lsylvester)
- * uses model name to determine the type
-- [#949](https://github.com/rails-api/active_model_serializers/pull/949) Don't pass serializer option to associated serializers (@bf4, @edwardloveall)
-- [#902](https://github.com/rails-api/active_model_serializers/pull/902) Added serializer file digest to the cache_key (@cristianbica)
-- [#948](https://github.com/rails-api/active_model_serializers/pull/948) AMS supports JSONAPI 1.0 instead of RC4 (@SeyZ)
-- [#936](https://github.com/rails-api/active_model_serializers/pull/936) Include meta when using json adapter with custom root (@chrisbranson)
-- [#942](https://github.com/rails-api/active_model_serializers/pull/942) Small code styling issue (@thiagofm)
-- [#930](https://github.com/rails-api/active_model_serializers/pull/930) Reverting PR #909 (@joaomdmoura)
-- [#924](https://github.com/rails-api/active_model_serializers/pull/924) Avoid unecessary calls to attribute methods when fragment caching (@navinpeiris)
-- [#925](https://github.com/rails-api/active_model_serializers/pull/925) Updates JSON API Adapter to generate RC4 schema (@benedikt)
- * adds JSON API support 1.0
-- [#918](https://github.com/rails-api/active_model_serializers/pull/918) Adding rescue_with_handler to clear state (@ryansch)
-- [#909](https://github.com/rails-api/active_model_serializers/pull/909) Defining Json-API Adapter as Default (@joaomdmoura)
- * remove root key option and split JSON adapter
-- [#914](https://github.com/rails-api/active_model_serializers/pull/914) Prevent possible duplicated attributes in serializer (@groyoh)
-- [#880](https://github.com/rails-api/active_model_serializers/pull/880) Inabling subclasses serializers to inherit attributes (@groyoh)
-- [#913](https://github.com/rails-api/active_model_serializers/pull/913) Avoiding the serializer option when instantiating a new one for ArraySerializer Fixed #911 (@groyoh)
-- [#897](https://github.com/rails-api/active_model_serializers/pull/897) Allow to define custom serializer for given class (@imanel)
-- [#892](https://github.com/rails-api/active_model_serializers/pull/892) Fixed a bug that appeared when json adapter serialize a nil association (@groyoh)
-- [#895](https://github.com/rails-api/active_model_serializers/pull/895) Adding a test to cover 'meta' and 'meta_key' attr_readers (@adomokos)
-- [#894](https://github.com/rails-api/active_model_serializers/pull/894) Fixing typos in README.md (@adomokos)
-- [#888](https://github.com/rails-api/active_model_serializers/pull/888) Changed duplicated test name in action controller test (@groyoh)
-- [#890](https://github.com/rails-api/active_model_serializers/pull/890) Remove unused method `def_serializer` (@JustinAiken)
-- [#887](https://github.com/rails-api/active_model_serializers/pull/887) Fixing tests on JRuby (@joaomdmoura)
-- [#885](https://github.com/rails-api/active_model_serializers/pull/885) Updates rails versions for test and dev (@tonyta)
-
-### [v0.10.0.rc1 (2015-04-22)](https://github.com/rails-api/active_model_serializers/compare/86fc7d7227f3ce538fcb28c1e8c7069ce311f0e1...v0.10.0.rc1)
-- [#810](https://github.com/rails-api/active_model_serializers/pull/810) Adding Fragment Cache to AMS (@joaomdmoura)
- * adds fragment cache support
-- [#868](https://github.com/rails-api/active_model_serializers/pull/868) Fixed a bug that appears when a nil association is included (@groyoh)
-- [#861](https://github.com/rails-api/active_model_serializers/pull/861) README: Add emphasis to single-word difference (@machty)
-- [#858](https://github.com/rails-api/active_model_serializers/pull/858) Included resource fixes (@mateomurphy)
-- [#853](https://github.com/rails-api/active_model_serializers/pull/853) RC3 Updates for JSON API (@mateomurphy)
-- [#852](https://github.com/rails-api/active_model_serializers/pull/852) Fix options merge order in `each_association` (@mateomurphy)
-- [#850](https://github.com/rails-api/active_model_serializers/pull/850) Use association value for determining serializer used (@mateomurphy)
-- [#843](https://github.com/rails-api/active_model_serializers/pull/843) Remove the mailing list from the README (@JoshSmith)
-- [#842](https://github.com/rails-api/active_model_serializers/pull/842) Add notes on how you can help to contributing documentation (@JoshSmith)
-- [#833](https://github.com/rails-api/active_model_serializers/pull/833) Cache serializers for class (@lsylvester)
-- [#837](https://github.com/rails-api/active_model_serializers/pull/837) Store options in array serializers (@kurko)
-- [#836](https://github.com/rails-api/active_model_serializers/pull/836) Makes passed in options accessible inside serializers (@kurko)
-- [#773](https://github.com/rails-api/active_model_serializers/pull/773) Make json api adapter 'include' option accept an array (@sweatypitts)
-- [#830](https://github.com/rails-api/active_model_serializers/pull/830) Add contributing readme (@JoshSmith)
-- [#811](https://github.com/rails-api/active_model_serializers/pull/811) Reimplement serialization scope and scope_name (@mateomurphy)
-- [#725](https://github.com/rails-api/active_model_serializers/pull/725) Support has_one to be compatible with 0.8.x (@ggordon)
- * adds `has_one` attribute for backwards compatibility
-- [#822](https://github.com/rails-api/active_model_serializers/pull/822) Replace has_one with attribute in template (@bf4)
-- [#821](https://github.com/rails-api/active_model_serializers/pull/821) Fix explicit serializer for associations (@wjordan)
-- [#798](https://github.com/rails-api/active_model_serializers/pull/798) Fix lost test `test_include_multiple_posts_and_linked` (@donbobka)
-- [#807](https://github.com/rails-api/active_model_serializers/pull/807) Add Overriding attribute methods section to README. (@alexstophel)
-- [#693](https://github.com/rails-api/active_model_serializers/pull/693) Cache Support at AMS 0.10.0 (@joaomdmoura)
- * adds cache support to attributes and associations.
-- [#792](https://github.com/rails-api/active_model_serializers/pull/792) Association overrides (@kurko)
- * adds method to override association
-- [#794](https://github.com/rails-api/active_model_serializers/pull/794) add to_param for correct URL generation (@carlesjove)
-
-### v0.10.0-pre
-
-- [Introduce Adapter](https://github.com/rails-api/active_model_serializers/commit/f00fe5595ddf741dc26127ed8fe81adad833ead5)
-- Prefer `ActiveModel::Serializer` to `ActiveModelSerializers`:
- - [Namespace](https://github.com/rails-api/active_model_serializers/commit/729a823868e8c7ac86c653fcc7100ee511e08cb6#diff-fe7aa2941c19a41ccea6e52940d84016).
- - [README](https://github.com/rails-api/active_model_serializers/commit/4a2d9853ba7486acc1747752982aa5650e7fd6e9).
-
-## 0.09.x
-
-### v0.9.3 (2015/01/21 20:29 +00:00)
-
-Features:
-- [#774](https://github.com/rails-api/active_model_serializers/pull/774) Fix nested include attributes (@nhocki)
-- [#771](https://github.com/rails-api/active_model_serializers/pull/771) Make linked resource type names consistent with root names (@sweatypitts)
-- [#696](https://github.com/rails-api/active_model_serializers/pull/696) Explicitly set serializer for associations (@ggordon)
-- [#700](https://github.com/rails-api/active_model_serializers/pull/700) sparse fieldsets (@arenoir)
-- [#768](https://github.com/rails-api/active_model_serializers/pull/768) Adds support for `meta` and `meta_key` attribute (@kurko)
-
-### v0.9.1 (2014/12/04 11:54 +00:00)
-- [#707](https://github.com/rails-api/active_model_serializers/pull/707) A Friendly Note on Which AMS Version to Use (@jherdman)
-- [#730](https://github.com/rails-api/active_model_serializers/pull/730) Fixes nested has_many links in JSONAPI (@kurko)
-- [#718](https://github.com/rails-api/active_model_serializers/pull/718) Allow overriding the adapter with render option (@ggordon)
-- [#720](https://github.com/rails-api/active_model_serializers/pull/720) Rename attribute with :key (0.8.x compatibility) (@ggordon)
-- [#728](https://github.com/rails-api/active_model_serializers/pull/728) Use type as key for linked resources (@kurko)
-- [#729](https://github.com/rails-api/active_model_serializers/pull/729) Use the new beta build env on Travis (@joshk)
-- [#703](https://github.com/rails-api/active_model_serializers/pull/703) Support serializer and each_serializer options in renderer (@ggordon, @mieko)
-- [#727](https://github.com/rails-api/active_model_serializers/pull/727) Includes links inside of linked resources (@kurko)
-- [#726](https://github.com/rails-api/active_model_serializers/pull/726) Bugfix: include nested has_many associations (@kurko)
-- [#722](https://github.com/rails-api/active_model_serializers/pull/722) Fix infinite recursion (@ggordon)
-- [#1](https://github.com/rails-api/active_model_serializers/pull/1) Allow for the implicit use of ArraySerializer when :each_serializer is specified (@mieko)
-- [#692](https://github.com/rails-api/active_model_serializers/pull/692) Include 'linked' member for json-api collections (@ggordon)
-- [#714](https://github.com/rails-api/active_model_serializers/pull/714) Define as_json instead of to_json (@guilleiguaran)
-- [#710](https://github.com/rails-api/active_model_serializers/pull/710) JSON-API: Don't include linked section if associations are empty (@guilleiguaran)
-- [#711](https://github.com/rails-api/active_model_serializers/pull/711) Fixes rbx gems bundling on TravisCI (@kurko)
-- [#709](https://github.com/rails-api/active_model_serializers/pull/709) Add type key when association name is different than object type (@guilleiguaran)
-- [#708](https://github.com/rails-api/active_model_serializers/pull/708) Handle correctly null associations (@guilleiguaran)
-- [#691](https://github.com/rails-api/active_model_serializers/pull/691) Fix embed option for associations (@jacob-s-son)
-- [#689](https://github.com/rails-api/active_model_serializers/pull/689) Fix support for custom root in JSON-API adapter (@guilleiguaran)
-- [#685](https://github.com/rails-api/active_model_serializers/pull/685) Serialize ids as strings in JSON-API adapter (@guilleiguaran)
-- [#684](https://github.com/rails-api/active_model_serializers/pull/684) Refactor adapters to implement support for array serialization (@guilleiguaran)
-- [#682](https://github.com/rails-api/active_model_serializers/pull/682) Include root by default in JSON-API serializers (@guilleiguaran)
-- [#625](https://github.com/rails-api/active_model_serializers/pull/625) Add DSL for urls (@JordanFaust)
-- [#677](https://github.com/rails-api/active_model_serializers/pull/677) Add support for embed: :ids option for in associations (@guilleiguaran)
-- [#681](https://github.com/rails-api/active_model_serializers/pull/681) Check superclasses for Serializers (@quainjn)
-- [#680](https://github.com/rails-api/active_model_serializers/pull/680) Add support for root keys (@NullVoxPopuli)
-- [#675](https://github.com/rails-api/active_model_serializers/pull/675) Support Rails 4.2.0 (@tricknotes)
-- [#667](https://github.com/rails-api/active_model_serializers/pull/667) Require only activemodel instead of full rails (@guilleiguaran)
-- [#653](https://github.com/rails-api/active_model_serializers/pull/653) Add "_test" suffix to JsonApi::HasManyTest filename. (@alexgenco)
-- [#631](https://github.com/rails-api/active_model_serializers/pull/631) Update build badge URL (@craiglittle)
-
-### 0.9.0.alpha1 - January 7, 2014
-
-### 0.9.0.pre
-
-* The following methods were removed
- - Model#active\_model\_serializer
- - Serializer#include!
- - Serializer#include?
- - Serializer#attr\_disabled=
- - Serializer#cache
- - Serializer#perform\_caching
- - Serializer#schema (needs more discussion)
- - Serializer#attribute
- - Serializer#include\_#{name}? (filter method added)
- - Serializer#attributes (took a hash)
-
-* The following things were added
- - Serializer#filter method
- - CONFIG object
-
-* Remove support for ruby 1.8 versions.
-
-* Require rails >= 3.2.
-
-* Serializers for associations are being looked up in a parent serializer's namespace first. Same with controllers' namespaces.
-
-* Added a "prefix" option in case you want to use a different version of serializer.
-
-* Serializers default namespace can be set in `default_serializer_options` and inherited by associations.
-
-* [Beginning of rewrite: c65d387705ec534db171712671ba7fcda4f49f68](https://github.com/rails-api/active_model_serializers/commit/c65d387705ec534db171712671ba7fcda4f49f68)
-
-## 0.08.x
-
-### v0.8.3 (2014/12/10 14:45 +00:00)
-- [#753](https://github.com/rails-api/active_model_serializers/pull/753) Test against Ruby 2.2 on Travis CI (@tricknotes)
-- [#745](https://github.com/rails-api/active_model_serializers/pull/745) Missing a word (@jockee)
-
-### v0.8.2 (2014/09/01 21:00 +00:00)
-- [#612](https://github.com/rails-api/active_model_serializers/pull/612) Feature/adapter (@bolshakov)
- * adds adapters pattern
-- [#615](https://github.com/rails-api/active_model_serializers/pull/615) Rails does not support const_defined? in development mode (@tpitale)
-- [#613](https://github.com/rails-api/active_model_serializers/pull/613) README: typo fix on attributes (@spk)
-- [#614](https://github.com/rails-api/active_model_serializers/pull/614) Fix rails 4.0.x build. (@arthurnn)
-- [#610](https://github.com/rails-api/active_model_serializers/pull/610) ArraySerializer (@bolshakov)
-- [#607](https://github.com/rails-api/active_model_serializers/pull/607) ruby syntax highlights (@zigomir)
-- [#602](https://github.com/rails-api/active_model_serializers/pull/602) Add DSL for associations (@JordanFaust)
-
-### 0.8.1 (May 6, 2013)
-
-* Fix bug whereby a serializer using 'options' would blow up.
-
-### 0.8.0 (May 5, 2013)
-
-* Attributes can now have optional types.
-
-* A new DefaultSerializer ensures that POROs behave the same way as ActiveModels.
-
-* If you wish to override ActiveRecord::Base#to_Json, you can now require
- 'active_record/serializer_override'. We don't recommend you do this, but
- many users do, so we've left it optional.
-
-* Fixed a bug where ActionController wouldn't always have MimeResponds.
-
-* An optinal caching feature allows you to cache JSON & hashes that AMS uses.
- Adding 'cached true' to your Serializers will turn on this cache.
-
-* URL helpers used inside of Engines now work properly.
-
-* Serializers now can filter attributes with `only` and `except`:
-
- ```
- UserSerializer.new(user, only: [:first_name, :last_name])
- UserSerializer.new(user, except: :first_name)
- ```
-
-* Basic Mongoid support. We now include our mixins in the right place.
-
-* On Ruby 1.8, we now generate an `id` method that properly serializes `id`
- columns. See issue #127 for more.
-
-* Add an alias for `scope` method to be the name of the context. By default
- this is `current_user`. The name is automatically set when using
- `serialization_scope` in the controller.
-
-* Pass through serialization options (such as `:include`) when a model
- has no serializer defined.
-
-## [0.7.0 (March 6, 2013)](https://github.com/rails-api/active_model_serializers/commit/fabdc621ff97fbeca317f6301973dd4564b9e695)
-
-* ```embed_key``` option to allow embedding by attributes other than IDs
-* Fix rendering nil with custom serializer
-* Fix global ```self.root = false```
-* Add support for specifying the serializer for an association as a String
-* Able to specify keys on the attributes method
-* Serializer Reloading via ActiveSupport::DescendantsTracker
-* Reduce double map to once; Fixes datamapper eager loading.
-
-## 0.6.0 (October 22, 2012)
-
-* Serialize sets properly
-* Add root option to ArraySerializer
-* Support polymorphic associations
-* Support :each_serializer in ArraySerializer
-* Add `scope` method to easily access the scope in the serializer
-* Fix regression with Rails 3.2.6; add Rails 4 support
-* Allow serialization_scope to be disabled with serialization_scope nil
-* Array serializer should support pure ruby objects besides serializers
-
-## 0.05.x
-
-### [0.5.2 (June 5, 2012)](https://github.com/rails-api/active_model_serializers/commit/615afd125c260432d456dc8be845867cf87ea118#diff-0c5c12f311d3b54734fff06069efd2ac)
-
-### [0.5.1 (May 23, 2012)](https://github.com/rails-api/active_model_serializers/commit/00194ec0e41831802fcbf893a34c0bb0853ebe14#diff-0c5c12f311d3b54734fff06069efd2ac)
-
-### [0.5.0 (May 16, 2012)](https://github.com/rails-api/active_model_serializers/commit/33d4842dcd35c7167b0b33fc0abcf00fb2c92286)
-
-* First tagged version
-* Changes generators to always generate an ApplicationSerializer
-
-## [0.1.0 (December 21, 2011)](https://github.com/rails-api/active_model_serializers/commit/1e0c9ef93b96c640381575dcd30be07ac946818b)
-
-## First Commit as [Rails Serializers 0.0.1](https://github.com/rails-api/active_model_serializers/commit/d72b66d4c5355b0ff0a75a04895fcc4ea5b0c65e)
- (December 1, 2011).
-
-## Prehistory
-
-- [Changing Serialization/Serializers namespace to `Serializable` (November 30, 2011)](https://github.com/rails/rails/commit/8896b4fdc8a543157cdf4dfc378607ebf6c10ab0)
- - [Merge branch 'serializers'. This implements the ActiveModel::Serializer object. Includes code, tests, generators and guides. From José and Yehuda with love.](https://github.com/rails/rails/commit/fcacc6986ab60f1fb2e423a73bf47c7abd7b191d)
- - But [was reverted](https://github.com/rails/rails/commit/5b2eb64ceb08cd005dc06b721935de5853971473).
- '[Revert the serializers API as other alternatives are now also under discussion](https://github.com/rails/rails/commit/0a4035b12a6c59253cb60f9e3456513c6a6a9d33)'.
-- [Proposed Implementation to Rails 3.2 by @wycats and @josevalim (November 25, 2011)](https://github.com/rails/rails/pull/3753)
- - [Creation of `ActionController::Serialization`, initial serializer
- support (September, 26 2011)](https://github.com/rails/rails/commit/8ff7693a8dc61f43fc4eaf72ed24d3b8699191fe).
- - [Docs and CHANGELOG](https://github.com/rails/rails/commit/696d01f7f4a8ed787924a41cce6df836cd73c46f)
- - [Deprecation of ActiveModel::Serialization to ActiveModel::Serializable](https://github.com/rails/rails/blob/696d01f7f4a8ed787924a41cce6df836cd73c46f/activemodel/lib/active_model/serialization.rb)
-- [Creation of `ActiveModel::Serialization` from `ActiveModel::Serializer` in Rails (2009)](https://github.com/rails/rails/commit/c6bc8e662614be711f45a8d4b231d5f993b024a7#diff-d029b9768d8df0407a35804a468e3ae5)
-- [Integration of `ActiveModel::Serializer` into `ActiveRecord::Serialization`](https://github.com/rails/rails/commit/783db25e0c640c1588732967a87d65c10fddc08e)
-- [Creation of `ActiveModel::Serializer` in Rails (2009)](https://github.com/rails/rails/commit/d2b78b3594b9cc9870e6a6ebfeb2e56d00e6ddb8#diff-80d5beeced9bdc24ca2b04a201543bdd)
-- [Creation of `ActiveModel::Serializers::JSON` in Rails (2009)](https://github.com/rails/rails/commit/fbdf706fffbfb17731a1f459203d242414ef5086)
+## [Prehistory](CHANGELOG-prehistory.md)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4c006f45..3ea519c4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -4,13 +4,7 @@ Before opening an issue, try the following:
##### Consult the documentation
-See if your issue can be resolved by information in the documentation.
-
-- [0.10 (master) Documentation](https://github.com/rails-api/active_model_serializers/tree/master/docs)
- - [](http://www.rubydoc.info/github/rails-api/active_model_serializers/v0.10.0)
- - [Guides](docs)
-- [0.9 (0-9-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-9-stable)
-- [0.8 (0-8-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-8-stable)
+See if your issue can be resolved by information in the [documentation](README.md).
##### Check for an existing issue
@@ -43,7 +37,9 @@ for discussion or add your comments to existing ones.
We also gladly welcome pull requests. When preparing to work on pull request,
please adhere to these standards:
-- Base work on the master branch unless fixing an issue with
+- Base work on the relevant branch:
+ [0.10-stable](https://github.com/rails-api/active_model_serializers/tree/0-10-stable)
+ or
[0.9-stable](https://github.com/rails-api/active_model_serializers/tree/0-9-stable)
or
[0.8-stable](https://github.com/rails-api/active_model_serializers/tree/0-8-stable)
@@ -52,10 +48,10 @@ please adhere to these standards:
- Note any specific areas that should be reviewed.
- Include tests.
- The test suite must pass on [supported Ruby versions](.travis.yml)
-- Include updates to the [documentation](https://github.com/rails-api/active_model_serializers/tree/master/docs)
+- Include updates to the [documentation](docs)
where applicable.
- Update the
- [CHANGELOG](https://github.com/rails-api/active_model_serializers/blob/master/CHANGELOG.md)
+ [CHANGELOG](CHANGELOG.md)
to the appropriate sections with a brief description of the changes.
- Do not change the VERSION file.
@@ -102,4 +98,3 @@ fi
unset RAILS_VERSION
done
```
-
diff --git a/Gemfile b/Gemfile
deleted file mode 100644
index e854a204..00000000
--- a/Gemfile
+++ /dev/null
@@ -1,56 +0,0 @@
-source 'https://rubygems.org'
-#
-# Add a Gemfile.local to locally bundle gems outside of version control
-local_gemfile = File.join(File.expand_path('..', __FILE__), 'Gemfile.local')
-eval_gemfile local_gemfile if File.readable?(local_gemfile)
-
-# Specify your gem's dependencies in active_model_serializers.gemspec
-gemspec
-
-version = ENV['RAILS_VERSION'] || '4.2'
-
-if version == 'master'
- gem 'rack', github: 'rack/rack'
- gem 'arel', github: 'rails/arel'
- git 'https://github.com/rails/rails.git' do
- gem 'railties'
- gem 'activesupport'
- gem 'activemodel'
- gem 'actionpack'
- gem 'activerecord', group: :test
- # Rails 5
- gem 'actionview'
- end
-else
- gem_version = "~> #{version}.0"
- gem 'railties', gem_version
- gem 'activesupport', gem_version
- gem 'activemodel', gem_version
- gem 'actionpack', gem_version
- gem 'activerecord', gem_version, group: :test
-end
-
-# https://github.com/bundler/bundler/blob/89a8778c19269561926cea172acdcda241d26d23/lib/bundler/dependency.rb#L30-L54
-@windows_platforms = [:mswin, :mingw, :x64_mingw]
-
-# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
-gem 'tzinfo-data', platforms: (@windows_platforms + [:jruby])
-
-group :bench do
- # https://github.com/rails-api/active_model_serializers/commit/cb4459580a6f4f37f629bf3185a5224c8624ca76
- gem 'benchmark-ips', '>= 2.7.2', require: false, group: :development
-end
-
-group :test do
- gem 'sqlite3', platform: (@windows_platforms + [:ruby])
- gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby
- gem 'codeclimate-test-reporter', require: false
- gem 'm', '~> 1.5'
- gem 'pry', '~> 0.10'
- gem 'pry-byebug', '~> 3.4', platform: :ruby
-end
-
-group :development, :test do
- gem 'rubocop', '~> 0.40.0', require: false
- gem 'yard', require: false
-end
diff --git a/README.md b/README.md
index 5bdcd20d..714c69ed 100644
--- a/README.md
+++ b/README.md
@@ -1,77 +1,11 @@
# ActiveModelSerializers
-
-
- | Build Status |
-
-
-
- |
-
-
- | Code Quality |
-
-
-
-
- |
-
-
- | Issue Stats |
-
- Pulse
- |
-
-
-
## About
-ActiveModelSerializers brings convention over configuration to your JSON generation.
-
-ActiveModelSerializers works through two components: **serializers** and **adapters**.
-
-Serializers describe _which_ attributes and relationships should be serialized.
-
-Adapters describe _how_ attributes and relationships should be serialized.
-
-SerializableResource co-ordinates the resource, Adapter and Serializer to produce the
-resource serialization. The serialization has the `#as_json`, `#to_json` and `#serializable_hash`
-methods used by the Rails JSON Renderer. (SerializableResource actually delegates
-these methods to the adapter.)
-
-By default ActiveModelSerializers will use the **Attributes Adapter** (no JSON root).
-But we strongly advise you to use **JsonApi Adapter**, which
-follows 1.0 of the format specified in [jsonapi.org/format](http://jsonapi.org/format).
-Check how to change the adapter in the sections below.
-
-`0.10.x` is **not** backward compatible with `0.9.x` nor `0.8.x`.
-
-`0.10.x` is based on the `0.8.0` code, but with a more flexible
-architecture. We'd love your help. [Learn how you can help here.](CONTRIBUTING.md)
-
-It is generally safe and recommended to use the master branch.
-
## Installation
-Add this line to your application's Gemfile:
-
-```
-gem 'active_model_serializers', '~> 0.10.0'
-```
-
-And then execute:
-
-```
-$ bundle
-```
-
## Getting Started
-See [Getting Started](docs/general/getting_started.md) for the nuts and bolts.
-
-More information is available in the [Guides](docs) and
-[High-level behavior](README.md#high-level-behavior).
-
## Getting Help
If you find a bug, please report an [Issue](https://github.com/rails-api/active_model_serializers/issues/new)
@@ -86,10 +20,11 @@ Thanks!
## Documentation
If you're reading this at https://github.com/rails-api/active_model_serializers you are
-reading documentation for our `master`, which may include features that have not
-been released yet. Please see below for the documentation relevant to you.
+reading documentation for our `master`, which is not yet released.
-- [0.10 (master) Documentation](https://github.com/rails-api/active_model_serializers/tree/master)
+Please see below for the documentation relevant to you.
+
+- [0.10 (0-10-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-10-stable)
- [0.10.6 (latest release) Documentation](https://github.com/rails-api/active_model_serializers/tree/v0.10.6)
- [](http://www.rubydoc.info/gems/active_model_serializers/0.10.6)
- [Guides](docs)
@@ -101,203 +36,8 @@ been released yet. Please see below for the documentation relevant to you.
## High-level behavior
-Choose an adapter from [adapters](lib/active_model_serializers/adapter):
-
-``` ruby
-ActiveModelSerializers.config.adapter = :json_api # Default: `:attributes`
-```
-
-Given a [serializable model](lib/active_model/serializer/lint.rb):
-
-```ruby
-# either
-class SomeResource < ActiveRecord::Base
- # columns: title, body
-end
-# or
-class SomeResource < ActiveModelSerializers::Model
- attributes :title, :body
-end
-```
-
-And initialized as:
-
-```ruby
-resource = SomeResource.new(title: 'ActiveModelSerializers', body: 'Convention over configuration')
-```
-
-Given a serializer for the serializable model:
-
-```ruby
-class SomeSerializer < ActiveModel::Serializer
- attribute :title, key: :name
- attributes :body
-end
-```
-
-The model can be serialized as:
-
-```ruby
-options = {}
-serialization = ActiveModelSerializers::SerializableResource.new(resource, options)
-serialization.to_json
-serialization.as_json
-```
-
-SerializableResource delegates to the adapter, which it builds as:
-
-```ruby
-adapter_options = {}
-adapter = ActiveModelSerializers::Adapter.create(serializer, adapter_options)
-adapter.to_json
-adapter.as_json
-adapter.serializable_hash
-```
-
-The adapter formats the serializer's attributes and associations (a.k.a. includes):
-
-```ruby
-serializer_options = {}
-serializer = SomeSerializer.new(resource, serializer_options)
-serializer.attributes
-serializer.associations
-```
-
## Architecture
-This section focuses on architecture the 0.10.x version of ActiveModelSerializers. If you are interested in the architecture of the 0.8 or 0.9 versions,
-please refer to the [0.8 README](https://github.com/rails-api/active_model_serializers/blob/0-8-stable/README.md) or
-[0.9 README](https://github.com/rails-api/active_model_serializers/blob/0-9-stable/README.md).
-
-The original design is also available [here](https://github.com/rails-api/active_model_serializers/blob/d72b66d4c5355b0ff0a75a04895fcc4ea5b0c65e/README.textile).
-
-### ActiveModel::Serializer
-
-An **`ActiveModel::Serializer`** wraps a [serializable resource](https://github.com/rails/rails/blob/4-2-stable/activemodel/lib/active_model/serialization.rb)
-and exposes an `attributes` method, among a few others.
-It allows you to specify which attributes and associations should be represented in the serializatation of the resource.
-It requires an adapter to transform its attributes into a JSON document; it cannot be serialized itself.
-It may be useful to think of it as a
-[presenter](http://blog.steveklabnik.com/posts/2011-09-09-better-ruby-presenters).
-
-#### ActiveModel::CollectionSerializer
-
-The **`ActiveModel::CollectionSerializer`** represents a collection of resources as serializers
-and, if there is no serializer, primitives.
-
-### ActiveModelSerializers::Adapter::Base
-
-The **`ActiveModelSerializeres::Adapter::Base`** describes the structure of the JSON document generated from a
-serializer. For example, the `Attributes` example represents each serializer as its
-unmodified attributes. The `JsonApi` adapter represents the serializer as a [JSON
-API](http://jsonapi.org/) document.
-
-### ActiveModelSerializers::SerializableResource
-
-The **`ActiveModelSerializers::SerializableResource`** acts to coordinate the serializer(s) and adapter
-to an object that responds to `to_json`, and `as_json`. It is used in the controller to
-encapsulate the serialization resource when rendered. However, it can also be used on its own
-to serialize a resource outside of a controller, as well.
-
-### Primitive handling
-
-Definitions: A primitive is usually a String or Array. There is no serializer
-defined for them; they will be serialized when the resource is converted to JSON (`as_json` or
-`to_json`). (The below also applies for any object with no serializer.)
-
-- ActiveModelSerializers doesn't handle primitives passed to `render json:` at all.
-
-Internally, if no serializer can be found in the controller, the resource is not decorated by
-ActiveModelSerializers.
-
-- However, when a primitive value is an attribute or in a collection, it is not modified.
-
-When serializing a collection and the collection serializer (CollectionSerializer) cannot
-identify a serializer for a resource in its collection, it throws [`:no_serializer`](https://github.com/rails-api/active_model_serializers/issues/1191#issuecomment-142327128).
-For example, when caught by `Reflection#build_association`, and the association value is set directly:
-
-```ruby
-reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
-```
-
-(which is called by the adapter as `serializer.associations(*)`.)
-
-### How options are parsed
-
-High-level overview:
-
-- For a **collection**
- - `:serializer` specifies the collection serializer and
- - `:each_serializer` specifies the serializer for each resource in the collection.
-- For a **single resource**, the `:serializer` option is the resource serializer.
-- Options are partitioned in serializer options and adapter options. Keys for adapter options are specified by
- [`ADAPTER_OPTION_KEYS`](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/serializable_resource.rb#L5).
- The remaining options are serializer options.
-
-Details:
-
-1. **ActionController::Serialization**
- 1. `serializable_resource = ActiveModelSerializers::SerializableResource.new(resource, options)`
- 1. `options` are partitioned into `adapter_opts` and everything else (`serializer_opts`).
- The `adapter_opts` keys are defined in [`ActiveModelSerializers::SerializableResource::ADAPTER_OPTION_KEYS`](lib/active_model_serializers/serializable_resource.rb#L5).
-1. **ActiveModelSerializers::SerializableResource**
- 1. `if serializable_resource.serializer?` (there is a serializer for the resource, and an adapter is used.)
- - Where `serializer?` is `use_adapter? && !!(serializer)`
- - Where `use_adapter?`: 'True when no explicit adapter given, or explicit value is truthy (non-nil);
- False when explicit adapter is falsy (nil or false)'
- - Where `serializer`:
- 1. from explicit `:serializer` option, else
- 2. implicitly from resource `ActiveModel::Serializer.serializer_for(resource)`
- 1. A side-effect of checking `serializer` is:
- - The `:serializer` option is removed from the serializer_opts hash
- - If the `:each_serializer` option is present, it is removed from the serializer_opts hash and set as the `:serializer` option
- 1. The serializer and adapter are created as
- 1. `serializer_instance = serializer.new(resource, serializer_opts)`
- 2. `adapter_instance = ActiveModel::Serializer::Adapter.create(serializer_instance, adapter_opts)`
-1. **ActiveModel::Serializer::CollectionSerializer#new**
- 1. If the `serializer_instance` was a `CollectionSerializer` and the `:serializer` serializer_opts
- is present, then [that serializer is passed into each resource](https://github.com/rails-api/active_model_serializers/blob/a54d237e2828fe6bab1ea5dfe6360d4ecc8214cd/lib/active_model/serializer/array_serializer.rb#L14-L16).
-1. **ActiveModel::Serializer#attributes** is used by the adapter to get the attributes for
- resource as defined by the serializer.
-
-(In Rails, the `options` are also passed to the `as_json(options)` or `to_json(options)`
-methods on the resource serialization by the Rails JSON renderer. They are, therefore, important
-to know about, but not part of ActiveModelSerializers.)
-
-### What does a 'serializable resource' look like?
-
-- An `ActiveRecord::Base` object.
-- Any Ruby object that passes the
- [Lint](http://www.rubydoc.info/github/rails-api/active_model_serializers/ActiveModel/Serializer/Lint/Tests)
- [code](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model/serializer/lint.rb).
-
-ActiveModelSerializers provides a
-[`ActiveModelSerializers::Model`](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/model.rb),
-which is a simple serializable PORO (Plain-Old Ruby Object).
-
-`ActiveModelSerializers::Model` may be used either as a reference implementation, or in production code.
-
-```ruby
-class MyModel < ActiveModelSerializers::Model
- attributes :id, :name, :level
-end
-```
-
-The default serializer for `MyModel` would be `MyModelSerializer` whether MyModel is an
-ActiveRecord::Base object or not.
-
-Outside of the controller the rules are **exactly** the same as for records. For example:
-
-```ruby
-render json: MyModel.new(level: 'awesome'), adapter: :json
-```
-
-would be serialized the same as
-
-```ruby
-ActiveModelSerializers::SerializableResource.new(MyModel.new(level: 'awesome'), adapter: :json).as_json
-```
-
## Semantic Versioning
This project adheres to [semver](http://semver.org/)
diff --git a/Rakefile b/Rakefile
index 6ba0c2bc..fbfba082 100644
--- a/Rakefile
+++ b/Rakefile
@@ -3,72 +3,3 @@ begin
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
-begin
- require 'simplecov'
-rescue LoadError # rubocop:disable Lint/HandleExceptions
-end
-import('lib/tasks/rubocop.rake')
-
-Bundler::GemHelper.install_tasks
-
-require 'yard'
-
-namespace :yard do
- YARD::Rake::YardocTask.new(:doc) do |t|
- t.stats_options = ['--list-undoc']
- end
-
- desc 'start a gem server'
- task :server do
- sh 'bundle exec yard server --gems'
- end
-
- desc 'use Graphviz to generate dot graph'
- task :graph do
- output_file = 'doc/erd.dot'
- sh "bundle exec yard graph --protected --full --dependencies > #{output_file}"
- puts 'open doc/erd.dot if you have graphviz installed'
- end
-end
-
-require 'rake/testtask'
-
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.libs << 'test'
- t.pattern = 'test/**/*_test.rb'
- t.ruby_opts = ['-r./test/test_helper.rb']
- t.ruby_opts << ' -w' unless ENV['NO_WARN'] == 'true'
- t.verbose = true
-end
-
-desc 'Run isolated tests'
-task isolated: ['test:isolated']
-namespace :test do
- task :isolated do
- desc 'Run isolated tests for Railtie'
- require 'shellwords'
- dir = File.dirname(__FILE__)
- dir = Shellwords.shellescape(dir)
- isolated_test_files = FileList['test/**/*_test_isolated.rb']
- # https://github.com/rails/rails/blob/3d590add45/railties/lib/rails/generators/app_base.rb#L345-L363
- _bundle_command = Gem.bin_path('bundler', 'bundle')
- require 'bundler'
- Bundler.with_clean_env do
- isolated_test_files.all? do |test_file|
- command = "-w -I#{dir}/lib -I#{dir}/test #{Shellwords.shellescape(test_file)}"
- full_command = %("#{Gem.ruby}" #{command})
- system(full_command)
- end or fail 'Failures' # rubocop:disable Style/AndOr
- end
- end
-end
-
-if ENV['RAILS_VERSION'].to_s > '4.0' && RUBY_ENGINE == 'ruby'
- task default: [:isolated, :test, :rubocop]
-else
- task default: [:test, :rubocop]
-end
-
-desc 'CI test task'
-task ci: [:default]
diff --git a/active_model_serializers.gemspec b/active_model_serializers.gemspec
index 805c99c8..02578620 100644
--- a/active_model_serializers.gemspec
+++ b/active_model_serializers.gemspec
@@ -1,11 +1,8 @@
# coding: utf-8
-lib = File.expand_path('../lib', __FILE__)
-$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
-require 'active_model/serializer/version'
Gem::Specification.new do |spec|
spec.name = 'active_model_serializers'
- spec.version = ActiveModel::Serializer::VERSION
+ spec.version = "1.0.0-dev"
spec.platform = Gem::Platform::RUBY
spec.authors = ['Steve Klabnik']
spec.email = ['steve@steveklabnik.com']
@@ -20,44 +17,4 @@ Gem::Specification.new do |spec|
spec.executables = []
spec.required_ruby_version = '>= 2.1'
-
- rails_versions = ['>= 4.1', '< 6']
- spec.add_runtime_dependency 'activemodel', rails_versions
- # 'activesupport', rails_versions
- # 'builder'
-
- spec.add_runtime_dependency 'actionpack', rails_versions
- # 'activesupport', rails_versions
- # 'rack'
- # 'rack-test', '~> 0.6.2'
-
- spec.add_development_dependency 'railties', rails_versions
- # 'activesupport', rails_versions
- # 'actionpack', rails_versions
- # 'rake', '>= 0.8.7'
-
- # 'activesupport', rails_versions
- # 'i18n,
- # 'tzinfo'
- # 'minitest'
- # 'thread_safe'
-
- spec.add_runtime_dependency 'jsonapi-renderer', ['>= 0.1.1.beta1', '< 0.2']
- spec.add_runtime_dependency 'case_transform', '>= 0.2'
-
- spec.add_development_dependency 'activerecord', rails_versions
- # arel
- # activesupport
- # activemodel
-
- # Soft dependency for pagination
- spec.add_development_dependency 'kaminari', ' ~> 0.16.3'
- spec.add_development_dependency 'will_paginate', '~> 3.0', '>= 3.0.7'
-
- spec.add_development_dependency 'bundler', '~> 1.6'
- spec.add_development_dependency 'simplecov', '~> 0.11'
- spec.add_development_dependency 'timecop', '~> 0.7'
- spec.add_development_dependency 'grape', ['>= 0.13', '< 0.19.1']
- spec.add_development_dependency 'json_schema'
- spec.add_development_dependency 'rake', ['>= 10.0', '< 12.0']
end
diff --git a/appveyor.yml b/appveyor.yml
index 7ecfa13a..aabf26a6 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -2,29 +2,10 @@ version: 1.0.{build}-{branch}
skip_tags: true
-environment:
- JRUBY_OPTS: "--dev -J-Xmx1024M --debug"
- matrix:
- - ruby_version: "Ruby21"
- - ruby_version: "Ruby21-x64"
-
cache:
- vendor/bundle
-install:
- - SET PATH=C:\%ruby_version%\bin;%PATH%
- - gem update --system
- - gem uninstall bundler -a -x
- - gem install bundler -v 1.13.7
- - bundle env
- - bundle install --path=vendor/bundle --retry=3 --jobs=3
-
-before_test:
- - ruby -v
- - gem -v
- - bundle -v
-
test_script:
- - bundle exec rake ci
+ - true
build: off
diff --git a/bin/bench b/bin/bench
deleted file mode 100755
index 8e8d5a49..00000000
--- a/bin/bench
+++ /dev/null
@@ -1,171 +0,0 @@
-#!/usr/bin/env ruby
-# ActiveModelSerializers Benchmark driver
-# Adapted from
-# https://github.com/ruby-bench/ruby-bench-suite/blob/8ad567f7e43a044ae48c36833218423bb1e2bd9d/rails/benchmarks/driver.rb
-require 'bundler'
-Bundler.setup
-require 'json'
-require 'pathname'
-require 'optparse'
-require 'digest'
-require 'pathname'
-require 'shellwords'
-require 'logger'
-require 'English'
-
-class BenchmarkDriver
- ROOT = Pathname File.expand_path(File.join('..', '..'), __FILE__)
- BASE = ENV.fetch('BASE') { ROOT.join('test', 'benchmark') }
- ESCAPED_BASE = Shellwords.shellescape(BASE)
-
- def self.benchmark(options)
- new(options).run
- end
-
- def self.parse_argv_and_run(argv = ARGV, options = {})
- options = {
- repeat_count: 1,
- pattern: [],
- env: 'CACHE_ON=on'
- }.merge!(options)
-
- OptionParser.new do |opts|
- opts.banner = 'Usage: bin/bench [options]'
-
- opts.on('-r', '--repeat-count [NUM]', 'Run benchmarks [NUM] times taking the best result') do |value|
- options[:repeat_count] = value.to_i
- end
-
- opts.on('-p', '--pattern ', 'Benchmark name pattern') do |value|
- options[:pattern] = value.split(',')
- end
-
- opts.on('-e', '--env ', 'ENV variables to pass in') do |value|
- options[:env] = value.split(',')
- end
- end.parse!(argv)
-
- benchmark(options)
- end
-
- attr_reader :commit_hash, :base
-
- # Based on logfmt:
- # https://www.brandur.org/logfmt
- # For more complete implementation see:
- # see https://github.com/arachnid-cb/logfmtr/blob/master/lib/logfmtr/base.rb
- # For usage see:
- # https://blog.codeship.com/logfmt-a-log-format-thats-easy-to-read-and-write/
- # https://engineering.heroku.com/blogs/2014-09-05-hutils-explore-your-structured-data-logs/
- # For Ruby parser see:
- # https://github.com/cyberdelia/logfmt-ruby
- def self.summary_logger(device = 'output.txt')
- require 'time'
- logger = Logger.new(device)
- logger.level = Logger::INFO
- logger.formatter = proc { |severity, datetime, progname, msg|
- msg = "'#{msg}'"
- "level=#{severity} time=#{datetime.utc.iso8601(6)} pid=#{Process.pid} progname=#{progname} msg=#{msg}#{$INPUT_RECORD_SEPARATOR}"
- }
- logger
- end
-
- def self.stdout_logger
- logger = Logger.new(STDOUT)
- logger.level = Logger::INFO
- logger.formatter = proc { |_, _, _, msg| "#{msg}#{$INPUT_RECORD_SEPARATOR}" }
- logger
- end
-
- def initialize(options)
- @writer = ENV['SUMMARIZE'] ? self.class.summary_logger : self.class.stdout_logger
- @repeat_count = options[:repeat_count]
- @pattern = options[:pattern]
- @commit_hash = options.fetch(:commit_hash) { `git rev-parse --short HEAD`.chomp }
- @base = options.fetch(:base) { ESCAPED_BASE }
- @env = Array(options[:env]).join(' ')
- @rubyopt = options[:rubyopt] # TODO: rename
- end
-
- def run
- files.each do |path|
- next if !@pattern.empty? && /#{@pattern.join('|')}/ !~ File.basename(path)
- run_single(Shellwords.shellescape(path))
- end
- end
-
- private
-
- def files
- Dir[File.join(base, 'bm_*')]
- end
-
- def run_single(path)
- script = "RAILS_ENV=production #{@env} ruby #{@rubyopt} #{path}"
- environment = `ruby -v`.chomp.strip[/\d+\.\d+\.\d+\w+/]
-
- runs_output = measure(script)
- if runs_output.empty?
- results = { error: :no_results }
- return
- end
-
- results = {}
- results['commit_hash'] = commit_hash
- results['version'] = runs_output.first['version']
- results['rails_version'] = runs_output.first['rails_version']
- results['benchmark_run[environment]'] = environment
- results['runs'] = []
-
- runs_output.each do |output|
- results['runs'] << {
- 'benchmark_type[category]' => output['label'],
- 'benchmark_run[result][iterations_per_second]' => output['iterations_per_second'].round(3),
- 'benchmark_run[result][total_allocated_objects_per_iteration]' => output['total_allocated_objects_per_iteration']
- }
- end
- ensure
- results && report(results)
- end
-
- def report(results)
- @writer.info { 'Benchmark results:' }
- @writer.info { JSON.pretty_generate(results) }
- end
-
- def summarize(result)
- puts "#{result['label']} #{result['iterations_per_second']}/ips; #{result['total_allocated_objects_per_iteration']} objects"
- end
-
- # FIXME: ` provides the full output but it'll return failed output as well.
- def measure(script)
- results = Hash.new { |h, k| h[k] = [] }
-
- @repeat_count.times do
- output = sh(script)
- output.each_line do |line|
- next if line.nil?
- begin
- result = JSON.parse(line)
- rescue JSON::ParserError
- result = { error: line } # rubocop:disable Lint/UselessAssignment
- else
- summarize(result)
- results[result['label']] << result
- end
- end
- end
-
- results.map do |_, bm_runs|
- bm_runs.sort_by do |run|
- run['iterations_per_second']
- end.last
- end
- end
-
- def sh(cmd)
- `#{cmd}`
- end
-end
-
-BenchmarkDriver.parse_argv_and_run if $PROGRAM_NAME == __FILE__
diff --git a/bin/bench_regression b/bin/bench_regression
deleted file mode 100755
index c4f00cba..00000000
--- a/bin/bench_regression
+++ /dev/null
@@ -1,316 +0,0 @@
-#!/usr/bin/env ruby
-require 'fileutils'
-require 'pathname'
-require 'shellwords'
-require 'English'
-
-############################
-# USAGE
-#
-# bundle exec bin/bench_regression
-# defaults to the current branch
-# defaults to the master branch
-# bundle exec bin/bench_regression current # will run on the current branch
-# bundle exec bin/bench_regression revisions 792fb8a90 master # every revision inclusive
-# bundle exec bin/bench_regression 792fb8a90 master --repeat-count 2 --env CACHE_ON=off
-# bundle exec bin/bench_regression vendor
-###########################
-
-class BenchRegression
- ROOT = Pathname File.expand_path(File.join(*['..', '..']), __FILE__)
- TMP_DIR_NAME = File.join('tmp', 'bench')
- TMP_DIR = File.join(ROOT, TMP_DIR_NAME)
- E_TMP_DIR = Shellwords.shellescape(TMP_DIR)
- load ROOT.join('bin', 'bench')
-
- attr_reader :source_stasher
-
- def initialize
- @source_stasher = SourceStasher.new
- end
-
- class SourceStasher
- attr_reader :gem_require_paths, :gem_paths
- attr_writer :vendor
-
- def initialize
- @gem_require_paths = []
- @gem_paths = []
- refresh_temp_dir
- @vendor = false
- end
-
- def temp_dir_empty?
- File.directory?(TMP_DIR) &&
- Dir[File.join(TMP_DIR, '*')].none?
- end
-
- def empty_temp_dir
- return if @vendor
- return if temp_dir_empty?
- FileUtils.mkdir_p(TMP_DIR)
- Dir[File.join(TMP_DIR, '*')].each do |file|
- if File.directory?(file)
- FileUtils.rm_rf(file)
- else
- FileUtils.rm(file)
- end
- end
- end
-
- def fill_temp_dir
- vendor_files(Dir[File.join(ROOT, 'test', 'benchmark', '*.{rb,ru}')])
- # vendor_file(File.join('bin', 'bench'))
- housekeeping { empty_temp_dir }
- vendor_gem('benchmark-ips')
- end
-
- def vendor_files(files)
- files.each do |file|
- vendor_file(file)
- end
- end
-
- def vendor_file(file)
- FileUtils.cp(file, File.join(TMP_DIR, File.basename(file)))
- end
-
- def vendor_gem(gem_name)
- directory_name = `bundle exec gem unpack benchmark-ips --target=#{E_TMP_DIR}`[/benchmark-ips.+\d/]
- gem_paths << File.join(TMP_DIR, directory_name)
- gem_require_paths << File.join(TMP_DIR_NAME, directory_name, 'lib')
- housekeeping { remove_vendored_gems }
- end
-
- def remove_vendored_gems
- return if @vendor
- FileUtils.rm_rf(*gem_paths)
- end
-
- def refresh_temp_dir
- empty_temp_dir
- fill_temp_dir
- end
-
- def housekeeping
- at_exit { yield }
- end
- end
-
- module RevisionMethods
- module_function
- def current_branch
- @current_branch ||= `cat .git/HEAD | cut -d/ -f3,4,5`.chomp
- end
-
- def current_revision
- `git rev-parse --short HEAD`.chomp
- end
-
- def revision_description(rev)
- `git log --oneline -1 #{rev}`.chomp
- end
-
- def revisions(start_ref, end_ref)
- cmd = "git rev-list --reverse #{start_ref}..#{end_ref}"
- `#{cmd}`.chomp.split("\n")
- end
-
- def checkout_ref(ref)
- `git checkout #{ref}`.chomp
- if $CHILD_STATUS
- STDERR.puts "Checkout failed: #{ref}, #{$CHILD_STATUS.exitstatus}" unless $CHILD_STATUS.success?
- $CHILD_STATUS.success?
- else
- true
- end
- end
-
- def clean_head
- system('git reset --hard --quiet')
- end
- end
- module ShellMethods
-
- def sh(cmd)
- puts cmd
- # system(cmd)
- run(cmd)
- # env = {}
- # # out = STDOUT
- # pid = spawn(env, cmd)
- # Process.wait(pid)
- # pid = fork do
- # exec cmd
- # end
- # Process.waitpid2(pid)
- # puts $CHILD_STATUS.exitstatus
- end
-
- require 'pty'
- # should consider trapping SIGINT in here
- def run(cmd)
- puts cmd
- child_process = ''
- result = ''
- # http://stackoverflow.com/a/1162850
- # stream output of subprocess
- begin
- PTY.spawn(cmd) do |stdin, _stdout, pid|
- begin
- # Do stuff with the output here. Just printing to show it works
- stdin.each do |line|
- print line
- result << line
- end
- child_process = PTY.check(pid)
- rescue Errno::EIO
- puts 'Errno:EIO error, but this probably just means ' \
- 'that the process has finished giving output'
- end
- end
- rescue PTY::ChildExited
- puts 'The child process exited!'
- end
- unless (child_process && child_process.success?)
- exitstatus = child_process.exitstatus
- puts "FAILED: #{child_process.pid} exited with status #{exitstatus.inspect} due to failed command #{cmd}"
- exit exitstatus || 1
- end
- result
- end
-
- def bundle(ref)
- system("rm -f Gemfile.lock")
- # This is absolutely critical for bundling to work
- Bundler.with_clean_env do
- system("bundle check ||
- bundle install --local ||
- bundle install ||
- bundle update")
- end
-
- # if $CHILD_STATUS
- # STDERR.puts "Bundle failed at: #{ref}, #{$CHILD_STATUS.exitstatus}" unless $CHILD_STATUS.success?
- # $CHILD_STATUS.success?
- # else
- # false
- # end
- end
- end
- include ShellMethods
- include RevisionMethods
-
- def benchmark_refs(ref1: nil, ref2: nil, cmd:)
- checking_out = false
- ref0 = current_branch
- ref1 ||= current_branch
- ref2 ||= 'master'
- p [ref0, ref1, ref2, current_revision]
-
- run_benchmark_at_ref(cmd, ref1)
- p [ref0, ref1, ref2, current_revision]
- run_benchmark_at_ref(cmd, ref2)
- p [ref0, ref1, ref2, current_revision]
-
- checking_out = true
- checkout_ref(ref0)
- rescue Exception # rubocop:disable Lint/RescueException
- STDERR.puts "[ERROR] #{$!.message}"
- checkout_ref(ref0) unless checking_out
- raise
- end
-
- def benchmark_revisions(ref1: nil, ref2: nil, cmd:)
- checking_out = false
- ref0 = current_branch
- ref1 ||= current_branch
- ref2 ||= 'master'
-
- revisions(ref1, ref2).each do |rev|
- STDERR.puts "Checking out: #{revision_description(rev)}"
-
- run_benchmark_at_ref(cmd, rev)
- clean_head
- end
- checking_out = true
- checkout_ref(ref0)
- rescue Exception # rubocop:disable Lint/RescueException
- STDERR.puts "[ERROR]: #{$!.message}"
- checkout_ref(ref0) unless checking_out
- raise
- end
-
- def run_benchmark_at_ref(cmd, ref)
- checkout_ref(ref)
- run_benchmark(cmd, ref)
- end
-
- def run_benchmark(cmd, ref = nil)
- ref ||= current_revision
- bundle(ref) &&
- benchmark_tests(cmd, ref)
- end
-
- def benchmark_tests(cmd, ref)
- base = E_TMP_DIR
- # cmd.sub('bin/bench', 'tmp/revision_runner/bench')
- # bundle = Gem.bin('bunle'
- # Bundler.with_clean_env(&block)
-
- # cmd = Shellwords.shelljoin(cmd)
- # cmd = "COMMIT_HASH=#{ref} BASE=#{base} bundle exec ruby -rbenchmark/ips #{cmd}"
- # Add vendoring benchmark/ips to load path
-
- # CURRENT THINKING: IMPORTANT
- # Pass into require statement as RUBYOPTS i.e. via env rather than command line argument
- # otherwise, have a 'fast ams benchmarking' module that extends benchmarkings to add the 'ams'
- # method but doesn't depend on benchmark-ips
- options = {
- commit_hash: ref,
- base: base,
- rubyopt: Shellwords.shellescape("-Ilib:#{source_stasher.gem_require_paths.join(':')}")
- }
- BenchmarkDriver.parse_argv_and_run(ARGV.dup, options)
- end
-end
-
-if $PROGRAM_NAME == __FILE__
- benchmarking = BenchRegression.new
-
- case ARGV[0]
- when 'current'
- # Run current branch only
-
- # super simple command line parsing
- args = ARGV.dup
- _ = args.shift # remove 'current' from args
- cmd = args
- benchmarking.run_benchmark(cmd)
- when 'revisions'
- # Runs on every revision
-
- # super simple command line parsing
- args = ARGV.dup
- _ = args.shift
- ref1 = args.shift # remove 'revisions' from args
- ref2 = args.shift
- cmd = args
- benchmarking.benchmark_revisions(ref1: ref1, ref2: ref2, cmd: cmd)
- when 'vendor'
- # Just prevents vendored files from being cleaned up
- # at exit. (They are vendored at initialize.)
- benchmarking.source_stasher.vendor = true
- else
- # Default: Compare current_branch to master
- # Optionally: pass in two refs as args to `bin/bench_regression`
- # TODO: Consider checking across more revisions, to automatically find problems.
-
- # super simple command line parsing
- args = ARGV.dup
- ref1 = args.shift
- ref2 = args.shift
- cmd = args
- benchmarking.benchmark_refs(ref1: ref1, ref2: ref2, cmd: cmd)
- end
-end
diff --git a/bin/rubocop b/bin/rubocop
deleted file mode 100755
index 269f8954..00000000
--- a/bin/rubocop
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env bash
-#
-# Usage:
-# bin/rubocop [-A|-t|-h]
-# bin/rubocop [file or path] [cli options]
-#
-# Options:
-# Autocorrect -A
-# AutoGenConfig -t
-# Usage -h,--help,help
-
-set -e
-
-case $1 in
- -A)
- echo "Rubocop autocorrect is ON" >&2
- bundle exec rake -f lib/tasks/rubocop.rake rubocop:auto_correct
- ;;
-
- -t)
- echo "Rubocop is generating a new TODO" >&2
- bundle exec rake -f lib/tasks/rubocop.rake rubocop:auto_gen_config
- ;;
-
- -h|--help|help)
- sed -ne '/^#/!q;s/.\{1,2\}//;1d;p' < "$0"
- ;;
-
- *)
- # with no args, run vanilla rubocop
- # else assume we're passing in arbitrary arguments
- if [ -z "$1" ]; then
- bundle exec rake -f lib/tasks/rubocop.rake rubocop
- else
- bundle exec rubocop "$@"
- fi
- ;;
-esac
diff --git a/bin/serve_benchmark b/bin/serve_benchmark
deleted file mode 100755
index 3f292d18..00000000
--- a/bin/serve_benchmark
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-case "$1" in
-
- start)
- config="${CONFIG_RU:-test/benchmark/config.ru}"
- bundle exec ruby -Ilib -S rackup "$config" --daemonize --pid tmp/benchmark_app.pid --warn --server webrick
- until [ -f 'tmp/benchmark_app.pid' ]; do
- sleep 0.1 # give it time to start.. I don't know a better way
- done
- cat tmp/benchmark_app.pid
- true
- ;;
-
- stop)
- if [ -f 'tmp/benchmark_app.pid' ]; then
- kill -TERM $(cat tmp/benchmark_app.pid)
- else
- echo 'No pidfile'
- false
- fi
- ;;
-
- status)
- if [ -f 'tmp/benchmark_app.pid' ]; then
- kill -0 $(cat tmp/benchmark_app.pid)
- [ "$?" -eq 0 ]
- else
- echo 'No pidfile'
- false
- fi
- ;;
-
- *)
- echo "Usage: $0 [start|stop|status]"
- ;;
-
-esac
diff --git a/docs/README.md b/docs/README.md
deleted file mode 100644
index 94460ec1..00000000
--- a/docs/README.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Docs - ActiveModel::Serializer 0.10.x
-
-This is the documentation of ActiveModelSerializers, it's focused on the **0.10.x version.**
-
------
-
-## General
-
-- [Getting Started](general/getting_started.md)
-- [Configuration Options](general/configuration_options.md)
-- [Serializers](general/serializers.md)
-- [Adapters](general/adapters.md)
-- [Rendering](general/rendering.md)
-- [Caching](general/caching.md)
-- [Logging](general/logging.md)
-- [Deserialization](general/deserialization.md)
-- [Instrumentation](general/instrumentation.md)
-- JSON API
- - [Schema](jsonapi/schema.md)
- - [Errors](jsonapi/errors.md)
-
-## How to
-
-- [How to add root key](howto/add_root_key.md)
-- [How to add pagination links](howto/add_pagination_links.md)
-- [How to add relationship links](howto/add_relationship_links.md)
-- [Using ActiveModelSerializers Outside Of Controllers](howto/outside_controller_use.md)
-- [Testing ActiveModelSerializers](howto/test.md)
-- [Passing Arbitrary Options](howto/passing_arbitrary_options.md)
-- [How to serialize a Plain-Old Ruby Object (PORO)](howto/serialize_poro.md)
-- [How to upgrade from `0.8` to `0.10` safely](howto/upgrade_from_0_8_to_0_10.md)
-
-## Integrations
-
-| Integration | Supported ActiveModelSerializers versions | Gem name and/or link
-|----|-----|----
-| Ember.js | 0.9.x | [active-model-adapter](https://github.com/ember-data/active-model-adapter)
-| Ember.js | 0.10.x + | [docs/integrations/ember-and-json-api.md](integrations/ember-and-json-api.md)
-| Grape | 0.10.x + | [docs/integrations/grape.md](integrations/grape.md) |
-| Grape | 0.9.x | https://github.com/jrhe/grape-active_model_serializers/ |
-| Sinatra | 0.9.x | https://github.com/SauloSilva/sinatra-active-model-serializers/
diff --git a/docs/STYLE.md b/docs/STYLE.md
deleted file mode 100644
index ccd75dd4..00000000
--- a/docs/STYLE.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# STYLE
-
-## Code and comments
-
-- We are actively working to identify tasks under the label [**Good for New
- Contributors**](https://github.com/rails-api/active_model_serializers/labels/Good%20for%20New%20Contributors).
- - [Changelog
- Missing](https://github.com/rails-api/active_model_serializers/issues?q=label%3A%22Changelog+Missing%22+is%3Aclosed) is
- an easy way to help out.
-
-- [Fix a bug](https://github.com/rails-api/active_model_serializers/labels/Ready%20for%20PR).
- - Ready for PR - A well defined bug, needs someone to PR a fix.
- - Bug - Anything that is broken.
- - Regression - A bug that did not exist in previous versions and isn't a new feature (applied in tandem with Bug).
- - Performance - A performance related issue. We could track this as a bug, but usually these would have slightly lower priority than standard bugs.
-
-- [Develop new features](https://github.com/rails-api/active_model_serializers/labels/Feature).
-
-- [Improve code quality](https://codeclimate.com/github/rails-api/active_model_serializers/code?sort=smell_count&sort_direction=desc).
-
-- [Improve amount of code exercised by tests](https://codeclimate.com/github/rails-api/active_model_serializers/coverage?sort=covered_percent&sort_direction=asc).
-
-- [Fix RuboCop (Style) TODOS](https://github.com/rails-api/active_model_serializers/blob/master/.rubocop_todo.yml).
- - Delete and offsense, run `rake rubocop` (or possibly `rake rubocop:auto_correct`),
- and [submit a PR](CONTRIBUTING.md#submitting-a-pull-request-pr).
-
-- We are also encouraging comments to substantial changes (larger than bugfixes and simple features) under an
- "RFC" (Request for Comments) process before we start active development.
- Look for the [**RFC**](https://github.com/rails-api/active_model_serializers/labels/RFC) label.
-
-
-## Pull requests
-
-- If the tests pass and the pull request looks good, a maintainer will merge it.
-- If the pull request needs to be changed,
- - you can change it by updating the branch you generated the pull request from
- - either by adding more commits, or
- - by force pushing to it
- - A maintainer can make any changes themselves and manually merge the code in.
-
-## Commit messages
-
-- [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
-- [http://stopwritingramblingcommitmessages.com/](http://stopwritingramblingcommitmessages.com/)
-- [ThoughtBot style guide](https://github.com/thoughtbot/guides/tree/master/style#git)
-
-#### About Pull Requests (PR's)
-
-- [Using Pull Requests](https://help.github.com/articles/using-pull-requests)
-- [Github pull requests made easy](http://www.element84.com/github-pull-requests-made-easy.html)
-- [Exercism Git Workflow](http://help.exercism.io/git-workflow.html).
-- [Level up your Git](http://rakeroutes.com/blog/deliberate-git/)
-- [All Your Open Source Code Are Belong To Us](http://www.benjaminfleischer.com/2013/07/30/all-your-open-source-code-are-belong-to-us/)
-
-## Issue Labeling
-
-ActiveModelSerializers uses a subset of [StandardIssueLabels](https://github.com/wagenet/StandardIssueLabels) for Github Issues. You can [see our labels here](https://github.com/rails-api/active_model_serializers/labels).
-
diff --git a/docs/general/adapters.md b/docs/general/adapters.md
deleted file mode 100644
index 84fc4e62..00000000
--- a/docs/general/adapters.md
+++ /dev/null
@@ -1,263 +0,0 @@
-[Back to Guides](../README.md)
-
-# Adapters
-
-ActiveModelSerializers offers the ability to configure which adapter
-to use both globally and/or when serializing (usually when rendering).
-
-The global adapter configuration is set on [`ActiveModelSerializers.config`](configuration_options.md).
-It should be set only once, preferably at initialization.
-
-For example:
-
-```ruby
-ActiveModelSerializers.config.adapter = ActiveModelSerializers::Adapter::JsonApi
-```
-
-or
-
-```ruby
-ActiveModelSerializers.config.adapter = :json_api
-```
-
-or
-
-```ruby
-ActiveModelSerializers.config.adapter = :json
-```
-
-The local adapter option is in the format `adapter: adapter`, where `adapter` is
-any of the same values as set globally.
-
-The configured adapter can be set as a symbol, class, or class name, as described in
-[Advanced adapter configuration](adapters.md#advanced-adapter-configuration).
-
-The `Attributes` adapter does not include a root key. It is just the serialized attributes.
-
-Use either the `JSON` or `JSON API` adapters if you want the response document to have a root key.
-
-## Built in Adapters
-
-### Attributes - Default
-
-It's the default adapter, it generates a json response without a root key.
-Doesn't follow any specific convention.
-
-##### Example output
-
-```json
-{
- "title": "Title 1",
- "body": "Body 1",
- "publish_at": "2020-03-16T03:55:25.291Z",
- "author": {
- "first_name": "Bob",
- "last_name": "Jones"
- },
- "comments": [
- {
- "body": "cool"
- },
- {
- "body": "awesome"
- }
- ]
-}
-```
-
-### JSON
-
-The json response is always rendered with a root key.
-
-The root key can be overridden by:
-* passing the `root` option in the render call. See details in the [Rendering Guides](rendering.md#overriding-the-root-key).
-* setting the `type` of the serializer. See details in the [Serializers Guide](serializers.md#type).
-
-Doesn't follow any specific convention.
-
-##### Example output
-
-```json
-{
- "post": {
- "title": "Title 1",
- "body": "Body 1",
- "publish_at": "2020-03-16T03:55:25.291Z",
- "author": {
- "first_name": "Bob",
- "last_name": "Jones"
- },
- "comments": [{
- "body": "cool"
- }, {
- "body": "awesome"
- }]
- }
-}
-```
-
-### JSON API
-
-This adapter follows **version 1.0** of the [format specified](../jsonapi/schema.md) in
-[jsonapi.org/format](http://jsonapi.org/format).
-
-##### Example output
-
-```json
-{
- "data": {
- "id": "1337",
- "type": "posts",
- "attributes": {
- "title": "Title 1",
- "body": "Body 1",
- "publish-at": "2020-03-16T03:55:25.291Z"
- },
- "relationships": {
- "author": {
- "data": {
- "id": "1",
- "type": "authors"
- }
- },
- "comments": {
- "data": [{
- "id": "7",
- "type": "comments"
- }, {
- "id": "12",
- "type": "comments"
- }]
- }
- },
- "links": {
- "post-authors": "https://example.com/post_authors"
- },
- "meta": {
- "rating": 5,
- "favorite-count": 10
- }
- }
-}
-```
-
-### Include option
-
-Which [serializer associations](https://github.com/rails-api/active_model_serializers/blob/master/docs/general/serializers.md#associations) are rendered can be specified using the `include` option. The option usage is consistent with [the include option in the JSON API spec](http://jsonapi.org/format/#fetching-includes), and is available in all adapters.
-
-Example of the usage:
-```ruby
- render json: @posts, include: ['author', 'comments', 'comments.author']
- # or
- render json: @posts, include: 'author,comments,comments.author'
-```
-
-The format of the `include` option can be either:
-
-- a String composed of a comma-separated list of [relationship paths](http://jsonapi.org/format/#fetching-includes).
-- an Array of Symbols and Hashes.
-- a mix of both.
-
-An empty string or an empty array will prevent rendering of any associations.
-
-In addition, two types of wildcards may be used:
-
-- `*` includes one level of associations.
-- `**` includes all recursively.
-
-These can be combined with other paths.
-
-```ruby
- render json: @posts, include: '**' # or '*' for a single layer
-```
-
-
-The following would render posts and include:
-
-- the author
-- the author's comments, and
-- every resource referenced by the author's comments (recursively).
-
-It could be combined, like above, with other paths in any combination desired.
-
-```ruby
- render json: @posts, include: 'author.comments.**'
-```
-
-**Note:** Wildcards are ActiveModelSerializers-specific, they are not part of the JSON API spec.
-
-The default include for the JSON API adapter is no associations. The default for the JSON and Attributes adapters is all associations.
-
-For the JSON API adapter associated resources will be gathered in the `"included"` member. For the JSON and Attributes
-adapters associated resources will be rendered among the other attributes.
-
-Only for the JSON API adapter you can specify, which attributes of associated resources will be rendered. This feature
-is called [sparse fieldset](http://jsonapi.org/format/#fetching-sparse-fieldsets):
-
-```ruby
- render json: @posts, include: 'comments', fields: { comments: ['content', 'created_at'] }
-```
-
-##### Security Considerations
-
-Since the included options may come from the query params (i.e. user-controller):
-
-```ruby
- render json: @posts, include: params[:include]
-```
-
-The user could pass in `include=**`.
-
-We recommend filtering any user-supplied includes appropriately.
-
-## Advanced adapter configuration
-
-### Registering an adapter
-
-The default adapter can be configured, as above, to use any class given to it.
-
-An adapter may also be specified, e.g. when rendering, as a class or as a symbol.
-If a symbol, then the adapter must be, e.g. `:great_example`,
-`ActiveModelSerializers::Adapter::GreatExample`, or registered.
-
-There are two ways to register an adapter:
-
-1) The simplest, is to subclass `ActiveModelSerializers::Adapter::Base`, e.g. the below will
-register the `Example::UsefulAdapter` as `"example/useful_adapter"`.
-
-```ruby
-module Example
- class UsefulAdapter < ActiveModelSerializers::Adapter::Base
- end
-end
-```
-
-You'll notice that the name it registers is the underscored namespace and class.
-
-Under the covers, when the `ActiveModelSerializers::Adapter::Base` is subclassed, it registers
-the subclass as `register("example/useful_adapter", Example::UsefulAdapter)`
-
-2) Any class can be registered as an adapter by calling `register` directly on the
-`ActiveModelSerializers::Adapter` class. e.g., the below registers `MyAdapter` as
-`:special_adapter`.
-
-```ruby
-class MyAdapter; end
-ActiveModelSerializers::Adapter.register(:special_adapter, MyAdapter)
-```
-
-### Looking up an adapter
-
-| Method | Return value |
-| :------------ |:---------------|
-| `ActiveModelSerializers::Adapter.adapter_map` | A Hash of all known adapters `{ adapter_name => adapter_class }` |
-| `ActiveModelSerializers::Adapter.adapters` | A (sorted) Array of all known `adapter_names` |
-| `ActiveModelSerializers::Adapter.lookup(name_or_klass)` | The `adapter_class`, else raises an `ActiveModelSerializers::Adapter::UnknownAdapter` error |
-| `ActiveModelSerializers::Adapter.adapter_class(adapter)` | Delegates to `ActiveModelSerializers::Adapter.lookup(adapter)` |
-| `ActiveModelSerializers::Adapter.configured_adapter` | A convenience method for `ActiveModelSerializers::Adapter.lookup(config.adapter)` |
-
-The registered adapter name is always a String, but may be looked up as a Symbol or String.
-Helpfully, the Symbol or String is underscored, so that `get(:my_adapter)` and `get("MyAdapter")`
-may both be used.
-
-For more information, see [the Adapter class on GitHub](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/adapter.rb)
diff --git a/docs/general/caching.md b/docs/general/caching.md
deleted file mode 100644
index 9ab9d71a..00000000
--- a/docs/general/caching.md
+++ /dev/null
@@ -1,58 +0,0 @@
-[Back to Guides](../README.md)
-
-# Caching
-
-## Warning
-
-There is currently a problem with caching in AMS [Caching doesn't improve performance](https://github.com/rails-api/active_model_serializers/issues/1586). Adding caching _may_ slow down your application, rather than speeding it up. We suggest you benchmark any caching you implement before using in a production enviroment
-
-___
-
-To cache a serializer, call ```cache``` and pass its options.
-The options are the same options of ```ActiveSupport::Cache::Store```, plus
-a ```key``` option that will be the prefix of the object cache
-on a pattern ```"#{key}/#{object.id}-#{object.updated_at}"```.
-
-The cache support is optimized to use the cached object in multiple request. An object cached on a ```show``` request will be reused at the ```index```. If there is a relationship with another cached serializer it will also be created and reused automatically.
-
-**[NOTE] Every object is individually cached.**
-
-**[NOTE] The cache is automatically expired after an object is updated, but it's not deleted.**
-
-```ruby
-cache(options = nil) # options: ```{key, expires_in, compress, force, race_condition_ttl}```
-```
-
-Take the example below:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- cache key: 'post', expires_in: 3.hours
- attributes :title, :body
-
- has_many :comments
-end
-```
-
-On this example every ```Post``` object will be cached with
-the key ```"post/#{post.id}-#{post.updated_at}"```. You can use this key to expire it as you want,
-but in this case it will be automatically expired after 3 hours.
-
-## Fragment Caching
-
-If there is some API endpoint that shouldn't be fully cached, you can still optimise it, using Fragment Cache on the attributes and relationships that you want to cache.
-
-You can define the attribute by using ```only``` or ```except``` option on cache method.
-
-**[NOTE] Cache serializers will be used at their relationships**
-
-Example:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- cache key: 'post', expires_in: 3.hours, only: [:title]
- attributes :title, :body
-
- has_many :comments
-end
-```
diff --git a/docs/general/configuration_options.md b/docs/general/configuration_options.md
deleted file mode 100644
index 83f8890d..00000000
--- a/docs/general/configuration_options.md
+++ /dev/null
@@ -1,169 +0,0 @@
-[Back to Guides](../README.md)
-
-# Configuration Options
-
-The following configuration options can be set on
-`ActiveModelSerializers.config`, preferably inside an initializer.
-
-## General
-
-##### adapter
-
-The [adapter](adapters.md) to use.
-
-Possible values:
-
-- `:attributes` (default)
-- `:json`
-- `:json_api`
-
-##### serializer_lookup_enabled
-
-Enable automatic serializer lookup.
-
-Possible values:
-
-- `true` (default)
-- `false`
-
-When `false`, serializers must be explicitly specified.
-
-##### key_transform
-
-The [key transform](key_transforms.md) to use.
-
-
-| Option | Result |
-|----|----|
-| `:camel` | ExampleKey |
-| `:camel_lower` | exampleKey |
-| `:dash` | example-key |
-| `:unaltered` | the original, unaltered key |
-| `:underscore` | example_key |
-| `nil` | use the adapter default |
-
-Each adapter has a default key transform configured:
-
-| Adapter | Default Key Transform |
-|----|----|
-| `Attributes` | `:unaltered` |
-| `Json` | `:unaltered` |
-| `JsonApi` | `:dash` |
-
-`config.key_transform` is a global override of the adapter default. Adapters
-still prefer the render option `:key_transform` over this setting.
-
-*NOTE: Key transforms can be expensive operations. If key transforms are unnecessary for the
-application, setting `config.key_transform` to `:unaltered` will provide a performance boost.*
-
-##### default_includes
-What relationships to serialize by default. Default: `'*'`, which includes one level of related
-objects. See [includes](adapters.md#included) for more info.
-
-
-##### serializer_lookup_chain
-
-Configures how serializers are searched for. By default, the lookup chain is
-
-```ruby
-ActiveModelSerializers::LookupChain::DEFAULT
-```
-
-which is shorthand for
-
-```ruby
-[
- ActiveModelSerializers::LookupChain::BY_PARENT_SERIALIZER,
- ActiveModelSerializers::LookupChain::BY_NAMESPACE,
- ActiveModelSerializers::LookupChain::BY_RESOURCE_NAMESPACE,
- ActiveModelSerializers::LookupChain::BY_RESOURCE
-]
-```
-
-Each of the array entries represent a proc. A serializer lookup proc will be yielded 3 arguments. `resource_class`, `serializer_class`, and `namespace`.
-
-Note that:
- - `resource_class` is the class of the resource being rendered
- - by default `serializer_class` is `ActiveModel::Serializer`
- - for association lookup it's the "parent" serializer
- - `namespace` correspond to either the controller namespace or the [optionally] specified [namespace render option](./rendering.md#namespace)
-
-An example config could be:
-
-```ruby
-ActiveModelSerializers.config.serializer_lookup_chain = [
- lambda do |resource_class, serializer_class, namespace|
- "API::#{namespace}::#{resource_class}"
- end
-]
-```
-
-If you simply want to add to the existing lookup_chain. Use `unshift`.
-
-```ruby
-ActiveModelSerializers.config.serializer_lookup_chain.unshift(
- lambda do |resource_class, serializer_class, namespace|
- # ...
- end
-)
-```
-
-See [lookup_chain.rb](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model_serializers/lookup_chain.rb) for further explanations and examples.
-
-## JSON API
-
-##### jsonapi_resource_type
-
-Sets whether the [type](http://jsonapi.org/format/#document-resource-identifier-objects)
-of the resource should be `singularized` or `pluralized` when it is not
-[explicitly specified by the serializer](https://github.com/rails-api/active_model_serializers/blob/master/docs/general/serializers.md#type)
-
-Possible values:
-
-- `:singular`
-- `:plural` (default)
-
-##### jsonapi_namespace_separator
-
-Sets separator string for namespaced models to render `type` attribute.
-
-
-| Separator | Example: Admin::User |
-|----|----|
-| `'-'` (default) | 'admin-users'
-| `'--'` (recommended) | 'admin--users'
-
-See [Recommendation for dasherizing (kebab-case-ing) namespaced object, such as `Admin::User`](https://github.com/json-api/json-api/issues/850)
-for more discussion.
-
-##### jsonapi_include_toplevel_object
-
-Include a [top level jsonapi member](http://jsonapi.org/format/#document-jsonapi-object)
-in the response document.
-
-Possible values:
-
-- `true`
-- `false` (default)
-
-##### jsonapi_version
-
-The latest version of the spec to which the API conforms.
-
-Default: `'1.0'`.
-
-*Used when `jsonapi_include_toplevel_object` is `true`*
-
-##### jsonapi_toplevel_meta
-
-Optional top-level metadata. Not included if empty.
-
-Default: `{}`.
-
-*Used when `jsonapi_include_toplevel_object` is `true`*
-
-
-## Hooks
-
-To run a hook when ActiveModelSerializers is loaded, use
-`ActiveSupport.on_load(:action_controller) do end`
diff --git a/docs/general/deserialization.md b/docs/general/deserialization.md
deleted file mode 100644
index 995abea9..00000000
--- a/docs/general/deserialization.md
+++ /dev/null
@@ -1,100 +0,0 @@
-[Back to Guides](../README.md)
-
-# Deserialization
-
-This is currently an *experimental* feature. The interface may change.
-
-## JSON API
-
-The `ActiveModelSerializers::Deserialization` defines two methods (namely `jsonapi_parse` and `jsonapi_parse!`), which take a `Hash` or an instance of `ActionController::Parameters` representing a JSON API payload, and return a hash that can directly be used to create/update models. The bang version throws an `InvalidDocument` exception when parsing fails, whereas the "safe" version simply returns an empty hash.
-
-- Parameters
- - document: `Hash` or `ActionController::Parameters` instance
- - options:
- - only: `Array` of whitelisted fields
- - except: `Array` of blacklisted fields
- - keys: `Hash` of fields the name of which needs to be modified (e.g. `{ :author => :user, :date => :created_at }`)
-
-Examples:
-
-```ruby
-class PostsController < ActionController::Base
- def create
- Post.create(create_params)
- end
-
- def create_params
- ActiveModelSerializers::Deserialization.jsonapi_parse(params, only: [:title, :content, :author])
- end
-end
-```
-
-
-
-Given a JSON API document,
-
-```
-document = {
- 'data' => {
- 'id' => 1,
- 'type' => 'post',
- 'attributes' => {
- 'title' => 'Title 1',
- 'date' => '2015-12-20'
- },
- 'relationships' => {
- 'author' => {
- 'data' => {
- 'type' => 'user',
- 'id' => '2'
- }
- },
- 'second_author' => {
- 'data' => nil
- },
- 'comments' => {
- 'data' => [{
- 'type' => 'comment',
- 'id' => '3'
- },{
- 'type' => 'comment',
- 'id' => '4'
- }]
- }
- }
- }
-}
-```
-
-The entire document can be parsed without specifying any options:
-```ruby
-ActiveModelSerializers::Deserialization.jsonapi_parse(document)
-#=>
-# {
-# title: 'Title 1',
-# date: '2015-12-20',
-# author_id: 2,
-# second_author_id: nil
-# comment_ids: [3, 4]
-# }
-```
-
-and fields, relationships, and polymorphic relationships can be specified via the options:
-
-```ruby
-ActiveModelSerializers::Deserialization
- .jsonapi_parse(document, only: [:title, :date, :author],
- keys: { date: :published_at },
- polymorphic: [:author])
-#=>
-# {
-# title: 'Title 1',
-# published_at: '2015-12-20',
-# author_id: '2',
-# author_type: 'user'
-# }
-```
-
-## Attributes/Json
-
-There is currently no deserialization for those adapters.
diff --git a/docs/general/fields.md b/docs/general/fields.md
deleted file mode 100644
index a1a12be6..00000000
--- a/docs/general/fields.md
+++ /dev/null
@@ -1,31 +0,0 @@
-[Back to Guides](../README.md)
-
-# Fields
-
-If for any reason, you need to restrict the fields returned, you should use `fields` option.
-
-For example, if you have a serializer like this
-
-```ruby
-class UserSerializer < ActiveModel::Serializer
- attributes :access_token, :first_name, :last_name
-end
-```
-
-and in a specific controller, you want to return `access_token` only, `fields` will help you:
-
-```ruby
-class AnonymousController < ApplicationController
- def create
- render json: User.create(activation_state: 'anonymous'), fields: [:access_token], status: 201
- end
-end
-```
-
-Note that this is only valid for the `json` and `attributes` adapter. For the `json_api` adapter, you would use
-
-```ruby
-render json: @user, fields: { users: [:access_token] }
-```
-
-Where `users` is the JSONAPI type.
diff --git a/docs/general/getting_started.md b/docs/general/getting_started.md
deleted file mode 100644
index b39cd283..00000000
--- a/docs/general/getting_started.md
+++ /dev/null
@@ -1,133 +0,0 @@
-[Back to Guides](../README.md)
-
-# Getting Started
-
-## Creating a Serializer
-
-The easiest way to create a new serializer is to generate a new resource, which
-will generate a serializer at the same time:
-
-```
-$ rails g resource post title:string body:string
-```
-
-This will generate a serializer in `app/serializers/post_serializer.rb` for
-your new model. You can also generate a serializer for an existing model with
-the serializer generator:
-
-```
-$ rails g serializer post
-```
-
-The generated serializer will contain basic `attributes` and
-`has_many`/`has_one`/`belongs_to` declarations, based on the model. For example:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attributes :title, :body
-
- has_many :comments
- has_one :author
-end
-```
-
-and
-
-```ruby
-class CommentSerializer < ActiveModel::Serializer
- attributes :name, :body
-
- belongs_to :post
-end
-```
-
-The attribute names are a **whitelist** of attributes to be serialized.
-
-The `has_many`, `has_one`, and `belongs_to` declarations describe relationships between
-resources. By default, when you serialize a `Post`, you will get its `Comments`
-as well.
-
-For more information, see [Serializers](/docs/general/serializers.md).
-
-### Namespaced Models
-
-When serializing a model inside a namespace, such as `Api::V1::Post`, ActiveModelSerializers will expect the corresponding serializer to be inside the same namespace (namely `Api::V1::PostSerializer`).
-
-### Model Associations and Nested Serializers
-
-When declaring a serializer for a model with associations, such as:
-```ruby
-class PostSerializer < ActiveModel::Serializer
- has_many :comments
-end
-```
-ActiveModelSerializers will look for `PostSerializer::CommentSerializer` in priority, and fall back to `::CommentSerializer` in case the former does not exist. This allows for more control over the way a model gets serialized as an association of an other model.
-
-For example, in the following situation:
-
-```ruby
-class CommentSerializer < ActiveModel::Serializer
- attributes :body, :date, :nb_likes
-end
-
-class PostSerializer < ActiveModel::Serializer
- has_many :comments
- class CommentSerializer < ActiveModel::Serializer
- attributes :body_short
- end
-end
-```
-
-ActiveModelSerializers will use `PostSerializer::CommentSerializer` (thus including only the `:body_short` attribute) when serializing a `Comment` as part of a `Post`, but use `::CommentSerializer` when serializing a `Comment` directly (thus including `:body, :date, :nb_likes`).
-
-### Extending a Base `ApplicationSerializer`
-
-By default, new serializers descend from `ActiveModel::Serializer`. However, if
-you wish to share behavior across your serializers, you can create an
-`ApplicationSerializer` at `app/serializers/application_serializer.rb`:
-
-```ruby
-class ApplicationSerializer < ActiveModel::Serializer
-end
-```
-
-Then any newly-generated serializers will automatically descend from
-`ApplicationSerializer`.
-
-```
-$ rails g serializer post
-```
-
-Now generates:
-
-```ruby
-class PostSerializer < ApplicationSerializer
- attributes :id
-end
-````
-
-## Rails Integration
-
-ActiveModelSerializers will automatically integrate with your Rails app,
-so you won't need to update your controller.
-This is a example of how the controller will look:
-
-```ruby
-class PostsController < ApplicationController
-
- def show
- @post = Post.find(params[:id])
- render json: @post
- end
-
-end
-```
-
-If you wish to use Rails url helpers for link generation, e.g., `link(:resources) { resources_url }`, ensure your application sets
-`Rails.application.routes.default_url_options`.
-
-```ruby
-Rails.application.routes.default_url_options = {
- host: 'example.com'
-}
-```
diff --git a/docs/general/instrumentation.md b/docs/general/instrumentation.md
deleted file mode 100644
index 560494ac..00000000
--- a/docs/general/instrumentation.md
+++ /dev/null
@@ -1,40 +0,0 @@
-[Back to Guides](../README.md)
-
-# Instrumentation
-
-ActiveModelSerializers uses the
-[ActiveSupport::Notification API](http://guides.rubyonrails.org/active_support_instrumentation.html#subscribing-to-an-event),
-which allows for subscribing to events, such as for logging.
-
-## Events
-
-Name:
-
-`render.active_model_serializers`
-
-Payload (example):
-
-```ruby
-{
- serializer: PostSerializer,
- adapter: ActiveModelSerializers::Adapter::Attributes
-}
-```
-
-Subscribing:
-
-```ruby
-ActiveSupport::Notifications.subscribe 'render.active_model_serializers' do |name, started, finished, unique_id, data|
- # whatever
-end
-ActiveSupport::Notifications.subscribe 'render.active_model_serializers' do |*args|
- event = ActiveSupport::Notifications::Event.new(*args)
- # event.payload
- # whatever
-end
-```
-
-## [LogSubscriber](http://api.rubyonrails.org/classes/ActiveSupport/LogSubscriber.html)
-
-ActiveModelSerializers includes an `ActiveModelSerializers::LogSubscriber` that attaches to
-`render.active_model_serializers`.
diff --git a/docs/general/key_transforms.md b/docs/general/key_transforms.md
deleted file mode 100644
index fd1be2d7..00000000
--- a/docs/general/key_transforms.md
+++ /dev/null
@@ -1,40 +0,0 @@
-[Back to Guides](../README.md)
-
-# Key Transforms
-
-Key Transforms modify the casing of keys and keys referenced in values in
-serialized responses.
-
-Provided key transforms:
-
-| Option | Result |
-|----|----|
-| `:camel` | ExampleKey |
-| `:camel_lower` | exampleKey |
-| `:dash` | example-key |
-| `:unaltered` | the original, unaltered key |
-| `:underscore` | example_key |
-| `nil` | use the adapter default |
-
-Key translation precedence is as follows:
-
-##### Adapter option
-
-`key_transform` is provided as an option via render.
-
-```render json: posts, each_serializer: PostSerializer, key_transform: :camel_lower```
-
-##### Configuration option
-
-`key_transform` is set in `ActiveModelSerializers.config.key_transform`.
-
-```ActiveModelSerializers.config.key_transform = :camel_lower```
-
-##### Adapter default
-
-Each adapter has a default transform configured:
-
-| Adapter | Default Key Transform |
-|----|----|
-| `Json` | `:unaltered` |
-| `JsonApi` | `:dash` |
diff --git a/docs/general/logging.md b/docs/general/logging.md
deleted file mode 100644
index 321bf5d8..00000000
--- a/docs/general/logging.md
+++ /dev/null
@@ -1,21 +0,0 @@
-[Back to Guides](../README.md)
-
-# Logging
-
-The default logger in a Rails application will be `Rails.logger`.
-
-When there is no `Rails.logger`, the default logger is an instance of
-`ActiveSupport::TaggedLogging` logging to STDOUT.
-
-You may customize the logger in an initializer, for example:
-
-```ruby
-ActiveModelSerializers.logger = Logger.new(STDOUT)
-```
-
-You can also disable the logger, just put this in `config/initializers/active_model_serializers.rb`:
-
-```ruby
-require 'active_model_serializers'
-ActiveSupport::Notifications.unsubscribe(ActiveModelSerializers::Logging::RENDER_EVENT)
-```
diff --git a/docs/general/rendering.md b/docs/general/rendering.md
deleted file mode 100644
index af2d886f..00000000
--- a/docs/general/rendering.md
+++ /dev/null
@@ -1,293 +0,0 @@
-[Back to Guides](../README.md)
-
-# Rendering
-
-### Implicit Serializer
-
-In your controllers, when you use `render :json`, Rails will now first search
-for a serializer for the object and use it if available.
-
-```ruby
-class PostsController < ApplicationController
- def show
- @post = Post.find(params[:id])
-
- render json: @post
- end
-end
-```
-
-In this case, Rails will look for a serializer named `PostSerializer`, and if
-it exists, use it to serialize the `Post`.
-
-### Explicit Serializer
-
-If you wish to use a serializer other than the default, you can explicitly pass it to the renderer.
-
-#### 1. For a resource:
-
-```ruby
- render json: @post, serializer: PostPreviewSerializer
-```
-
-#### 2. For a resource collection:
-
-Specify the serializer for each resource with `each_serializer`
-
-```ruby
-render json: @posts, each_serializer: PostPreviewSerializer
-```
-
-The default serializer for collections is `CollectionSerializer`.
-
-Specify the collection serializer with the `serializer` option.
-
-```ruby
-render json: @posts, serializer: CollectionSerializer, each_serializer: PostPreviewSerializer
-```
-
-## Serializing non-ActiveRecord objects
-
-See [README](../../README.md#what-does-a-serializable-resource-look-like)
-
-## SerializableResource options
-
-See [README](../../README.md#activemodelserializersserializableresource)
-
-### adapter_opts
-
-#### fields
-
-If you are using `json` or `attributes` adapter
-```ruby
-render json: @user, fields: [:access_token]
-```
-
-See [Fields](fields.md) for more information.
-
-#### adapter
-
-This option lets you explicitly set the adapter to be used by passing a registered adapter. Your options are `:attributes`, `:json`, and `:json_api`.
-
-```
-ActiveModel::Serializer.config.adapter = :json_api
-```
-
-#### key_transform
-
-```render json: posts, each_serializer: PostSerializer, key_transform: :camel_lower```
-
-See [Key Transforms](key_transforms.md) for more information.
-
-#### meta
-
-A `meta` member can be used to include non-standard meta-information. `meta` can
-be utilized in several levels in a response.
-
-##### Top-level
-
-To set top-level `meta` in a response, specify it in the `render` call.
-
-```ruby
-render json: @post, meta: { total: 10 }
-```
-
-The key can be customized using `meta_key` option.
-
-```ruby
-render json: @post, meta: { total: 10 }, meta_key: "custom_meta"
-```
-
-`meta` will only be included in your response if you are using an Adapter that
-supports `root`, e.g., `JsonApi` and `Json` adapters. The default adapter,
-`Attributes` does not have `root`.
-
-
-##### Resource-level
-
-To set resource-level `meta` in a response, define meta in a serializer with one
-of the following methods:
-
-As a single, static string.
-
-```ruby
-meta stuff: 'value'
-```
-
-As a block containing a Hash.
-
-```ruby
-meta do
- {
- rating: 4,
- comments_count: object.comments.count
- }
-end
-```
-
-
-#### links
-
-If you wish to use Rails url helpers for link generation, e.g., `link(:resources) { resources_url }`, ensure your application sets
-`Rails.application.routes.default_url_options`.
-
-##### Top-level
-
-JsonApi supports a [links object](http://jsonapi.org/format/#document-links) to be specified at top-level, that you can specify in the `render`:
-
-```ruby
- links_object = {
- href: "http://example.com/api/posts",
- meta: {
- count: 10
- }
- }
- render json: @posts, links: links_object
-```
-
-That's the result:
-
-```json
-{
- "data": [
- {
- "type": "posts",
- "id": "1",
- "attributes": {
- "title": "JSON API is awesome!",
- "body": "You should be using JSON API",
- "created": "2015-05-22T14:56:29.000Z",
- "updated": "2015-05-22T14:56:28.000Z"
- }
- }
- ],
- "links": {
- "href": "http://example.com/api/posts",
- "meta": {
- "count": 10
- }
- }
-}
-```
-
-This feature is specific to JsonApi, so you have to use the use the [JsonApi Adapter](adapters.md#jsonapi)
-
-
-##### Resource-level
-
-In your serializer, define each link in one of the following methods:
-
-As a static string
-
-```ruby
-link :link_name, 'https://example.com/resource'
-```
-
-As a block to be evaluated. When using Rails, URL helpers are available.
-Ensure your application sets `Rails.application.routes.default_url_options`.
-
-```ruby
-link :link_name_ do
- "https://example.com/resource/#{object.id}"
-end
-
-link(:link_name) { "https://example.com/resource/#{object.id}" }
-
-link(:link_name) { resource_url(object) }
-
-link(:link_name) { url_for(controller: 'controller_name', action: 'index', only_path: false) }
-
-```
-
-### serializer_opts
-
-#### include
-
-See [Adapters: Include Option](/docs/general/adapters.md#include-option).
-
-#### Overriding the root key
-
-Overriding the resource root only applies when using the JSON adapter.
-
-Normally, the resource root is derived from the class name of the resource being serialized.
-e.g. `UserPostSerializer.new(UserPost.new)` will be serialized with the root `user_post` or `user_posts` according the adapter collection pluralization rules.
-
-When using the JSON adapter in your initializer (ActiveModelSerializers.config.adapter = :json), or passing in the adapter in your render call, you can specify the root by passing it as an argument to `render`. For example:
-
-```ruby
- render json: @user_post, root: "admin_post", adapter: :json
-```
-
-This will be rendered as:
-```json
- {
- "admin_post": {
- "title": "how to do open source"
- }
- }
-```
-Note: the `Attributes` adapter (default) does not include a resource root. You also will not be able to create a single top-level root if you are using the :json_api adapter.
-
-#### namespace
-
-The namespace for serializer lookup is based on the controller.
-
-To configure the implicit namespace, in your controller, create a before filter
-
-```ruby
-before_action do
- self.namespace_for_serializer = Api::V2
-end
-```
-
-`namespace` can also be passed in as a render option:
-
-
-```ruby
-@post = Post.first
-render json: @post, namespace: Api::V2
-```
-
-This tells the serializer lookup to check for the existence of `Api::V2::PostSerializer`, and if any relations are rendered with `@post`, they will also utilize the `Api::V2` namespace.
-
-The `namespace` can be any object whose namespace can be represented by string interpolation (i.e. by calling to_s)
-- Module `Api::V2`
-- String `'Api::V2'`
-- Symbol `:'Api::V2'`
-
-Note that by using a string and symbol, Ruby will assume the namespace is defined at the top level.
-
-
-#### serializer
-
-Specify which serializer to use if you want to use a serializer other than the default.
-
-For a single resource:
-
-```ruby
-@post = Post.first
-render json: @post, serializer: SpecialPostSerializer
-```
-
-To specify which serializer to use on individual items in a collection (i.e., an `index` action), use `each_serializer`:
-
-```ruby
-@posts = Post.all
-render json: @posts, each_serializer: SpecialPostSerializer
-```
-
-#### scope
-
-See [Serializers: Scope](/docs/general/serializers.md#scope).
-
-#### scope_name
-
-See [Serializers: Scope](/docs/general/serializers.md#scope).
-
-## Using a serializer without `render`
-
-See [Usage outside of a controller](../howto/outside_controller_use.md#serializing-before-controller-render).
-
-## Pagination
-
-See [How to add pagination links](https://github.com/rails-api/active_model_serializers/blob/master/docs/howto/add_pagination_links.md).
diff --git a/docs/general/serializers.md b/docs/general/serializers.md
deleted file mode 100644
index 5b23ba0f..00000000
--- a/docs/general/serializers.md
+++ /dev/null
@@ -1,480 +0,0 @@
-[Back to Guides](../README.md)
-
-# Serializers
-
-Given a serializer class:
-
-```ruby
-class SomeSerializer < ActiveModel::Serializer
-end
-```
-
-The following methods may be defined in it:
-
-### Attributes
-
-#### ::attributes
-
-Serialization of the resource `title` and `body`
-
-| In Serializer | #attributes |
-|---------------------------- |-------------|
-| `attributes :title, :body` | `{ title: 'Some Title', body: 'Some Body' }`
-| `attributes :title, :body`
`def body "Special #{object.body}" end` | `{ title: 'Some Title', body: 'Special Some Body' }`
-
-
-#### ::attribute
-
-Serialization of the resource `title`
-
-| In Serializer | #attributes |
-|---------------------------- |-------------|
-| `attribute :title` | `{ title: 'Some Title' } `
-| `attribute :title, key: :name` | `{ name: 'Some Title' } `
-| `attribute(:title) { 'A Different Title'}` | `{ title: 'A Different Title' } `
-| `attribute :title`
`def title 'A Different Title' end` | `{ title: 'A Different Title' }`
-
-An `if` or `unless` option can make an attribute conditional. It takes a symbol of a method name on the serializer, or a lambda literal.
-
-e.g.
-
-```ruby
-attribute :private_data, if: :is_current_user?
-attribute :another_private_data, if: -> { scope.admin? }
-
-def is_current_user?
- object.id == current_user.id
-end
-```
-
-### Associations
-
-The interface for associations is, generically:
-
-> `association_type(association_name, options, &block)`
-
-Where:
-
-- `association_type` may be `has_one`, `has_many`, `belongs_to`.
-- `association_name` is a method name the serializer calls.
-- optional: `options` may be:
- - `key:` The name used for the serialized association.
- - `serializer:`
- - `if:`
- - `unless:`
- - `virtual_value:`
- - `polymorphic:` defines if polymorphic relation type should be nested in serialized association.
- - `type:` the resource type as used by JSON:API, especially on a `belongs_to` relationship.
- - `class_name:` used to determine `type` when `type` not given
- - `foreign_key:` used by JSON:API on a `belongs_to` relationship to avoid unnecessarily loading the association object.
- - `namespace:` used when looking up the serializer and `serializer` is not given. Falls back to the parent serializer's `:namespace` instance options, which, when present, comes from the render options. See [Rendering#namespace](rendering.md#namespace] for more details.
-- optional: `&block` is a context that returns the association's attributes.
- - prevents `association_name` method from being called.
- - return value of block is used as the association value.
- - yields the `serializer` to the block.
- - `include_data false` prevents the `data` key from being rendered in the JSON API relationship.
-
-#### ::has_one
-
-e.g.
-
-```ruby
-has_one :bio
-has_one :blog, key: :site
-has_one :maker, virtual_value: { id: 1 }
-
-has_one :blog do |serializer|
- serializer.cached_blog
-end
-
-def cached_blog
- cache_store.fetch("cached_blog:#{object.updated_at}") do
- Blog.find(object.blog_id)
- end
-end
-```
-
-```ruby
-has_one :blog, if: :show_blog?
-# you can also use a string or lambda
-# has_one :blog, if: 'scope.admin?'
-# has_one :blog, if: -> (serializer) { serializer.scope.admin? }
-# has_one :blog, if: -> { scope.admin? }
-
-def show_blog?
- scope.admin?
-end
-```
-
-#### ::has_many
-
-e.g.
-
-```ruby
-has_many :comments
-has_many :comments, key: :reviews
-has_many :comments, serializer: CommentPreviewSerializer
-has_many :reviews, virtual_value: [{ id: 1 }, { id: 2 }]
-has_many :comments, key: :last_comments do
- last(1)
-end
-```
-
-#### ::belongs_to
-
-e.g.
-
-```ruby
-belongs_to :author, serializer: AuthorPreviewSerializer
-belongs_to :author, key: :writer
-belongs_to :post
-belongs_to :blog
-def blog
- Blog.new(id: 999, name: 'Custom blog')
-end
-```
-
-### Polymorphic Relationships
-
-Polymorphic relationships are serialized by specifying the relationship, like any other association. For example:
-
-```ruby
-class PictureSerializer < ActiveModel::Serializer
- has_one :imageable
-end
-```
-
-You can specify the serializers by [overriding serializer_for](serializers.md#overriding-association-serializer-lookup). For more context about polymorphic relationships, see the [tests](../../test/adapter/polymorphic_test.rb) for each adapter.
-
-### Caching
-
-#### ::cache
-
-e.g.
-
-```ruby
-cache key: 'post', expires_in: 0.1, skip_digest: true
-cache expires_in: 1.day, skip_digest: true
-cache key: 'writer', skip_digest: true
-cache only: [:name], skip_digest: true
-cache except: [:content], skip_digest: true
-cache key: 'blog'
-cache only: [:id]
-```
-
-#### #cache_key
-
-e.g.
-
-```ruby
-# Uses a custom non-time-based cache key
-def cache_key
- "#{self.class.name.downcase}/#{self.id}"
-end
-```
-
-### Other
-
-#### ::type
-
-When using the `:json_api` adapter, the `::type` method defines the JSONAPI [type](http://jsonapi.org/format/#document-resource-object-identification) that will be rendered for this serializer.
-
-When using the `:json` adapter, the `::type` method defines the name of the root element.
-
-It either takes a `String` or `Symbol` as parameter.
-
-Note: This method is useful only when using the `:json_api` or `:json` adapter.
-
-Examples:
-```ruby
-class UserProfileSerializer < ActiveModel::Serializer
- type 'profile'
-
- attribute :name
-end
-class AuthorProfileSerializer < ActiveModel::Serializer
- type :profile
-
- attribute :name
-end
-```
-
-With the `:json_api` adapter, the previous serializers would be rendered as:
-
-``` json
-{
- "data": {
- "id": "1",
- "type": "profile",
- "attributes": {
- "name": "Julia"
- }
- }
-}
-```
-
-With the `:json` adapter, the previous serializer would be rendered as:
-
-``` json
-{
- "profile": {
- "name": "Julia"
- }
-}
-```
-
-#### ::link
-
-```ruby
-link :self do
- href "https://example.com/link_author/#{object.id}"
-end
-link(:author) { link_author_url(object) }
-link(:link_authors) { link_authors_url }
-link :other, 'https://example.com/resource'
-link(:posts) { link_author_posts_url(object) }
-```
-
-#### #object
-
-The object being serialized.
-
-#### #root
-
-Resource root which is included in `JSON` adapter. As you can see at [Adapters Document](adapters.md), `Attribute` adapter (default) and `JSON API` adapter does not include root at top level.
-By default, the resource root comes from the `model_name` of the serialized object's class.
-
-There are several ways to specify root:
-* [Overriding the root key](rendering.md#overriding-the-root-key)
-* [Setting `type`](serializers.md#type)
-* Specifying the `root` option, e.g. `root: 'specific_name'`, during the serializer's initialization:
-
-```ruby
-ActiveModelSerializers::SerializableResource.new(foo, root: 'bar')
-```
-
-#### #scope
-
-Allows you to include in the serializer access to an external method.
-
-It's intended to provide an authorization context to the serializer, so that
-you may e.g. show an admin all comments on a post, else only published comments.
-
-- `scope` is a method on the serializer instance that comes from `options[:scope]`. It may be nil.
-- `scope_name` is an option passed to the new serializer (`options[:scope_name]`). The serializer
- defines a method with that name that calls the `scope`, e.g. `def current_user; scope; end`.
- Note: it does not define the method if the serializer instance responds to it.
-
-That's a lot of words, so here's some examples:
-
-First, let's assume the serializer is instantiated in the controller, since that's the usual scenario.
-We'll refer to the serialization context as `controller`.
-
-| options | `Serializer#scope` | method definition |
-|-------- | ------------------|--------------------|
-| `scope: current_user, scope_name: :current_user` | `current_user` | `Serializer#current_user` calls `controller.current_user`
-| `scope: view_context, scope_name: :view_context` | `view_context` | `Serializer#view_context` calls `controller.view_context`
-
-We can take advantage of the scope to customize the objects returned based
-on the current user (scope).
-
-For example, we can limit the posts the current user sees to those they created:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body
-
- # scope comments to those created_by the current user
- has_many :comments do
- object.comments.where(created_by: current_user)
- end
-end
-```
-
-Whether you write the method as above or as `object.comments.where(created_by: scope)`
-is a matter of preference (assuming `scope_name` has been set).
-
-##### Controller Authorization Context
-
-In the controller, the scope/scope_name options are equal to
-the [`serialization_scope`method](https://github.com/rails-api/active_model_serializers/blob/d02cd30fe55a3ea85e1d351b6e039620903c1871/lib/action_controller/serialization.rb#L13-L20),
-which is `:current_user`, by default.
-
-Specifically, the `scope_name` is defaulted to `:current_user`, and may be set as
-`serialization_scope :view_context`. The `scope` is set to `send(scope_name)` when `scope_name` is
-present and the controller responds to `scope_name`.
-
-Thus, in a serializer, the controller provides `current_user` as the
-current authorization scope when you call `render :json`.
-
-**IMPORTANT**: Since the scope is set at render, you may want to customize it so that `current_user` isn't
-called on every request. This was [also a problem](https://github.com/rails-api/active_model_serializers/pull/1252#issuecomment-159810477)
-in [`0.9`](https://github.com/rails-api/active_model_serializers/tree/0-9-stable#customizing-scope).
-
-We can change the scope from `current_user` to `view_context`.
-
-```diff
-class SomeController < ActionController::Base
-+ serialization_scope :view_context
-
- def current_user
- User.new(id: 2, name: 'Bob', admin: true)
- end
-
- def edit
- user = User.new(id: 1, name: 'Pete')
- render json: user, serializer: AdminUserSerializer, adapter: :json_api
- end
-end
-```
-
-We could then use the controller method `view_context` in our serializer, like so:
-
-```diff
-class AdminUserSerializer < ActiveModel::Serializer
- attributes :id, :name, :can_edit
-
- def can_edit?
-+ view_context.current_user.admin?
- end
-end
-```
-
-So that when we render the `#edit` action, we'll get
-
-```json
-{"data":{"id":"1","type":"users","attributes":{"name":"Pete","can_edit":true}}}
-```
-
-Where `can_edit` is `view_context.current_user.admin?` (true).
-
-You can also tell what to set as `serialization_scope` for specific actions.
-
-For example, use `admin_user` only for `Admin::PostSerializer` and `current_user` for rest.
-
-```ruby
-class PostsController < ActionController::Base
-
- before_action only: :edit do
- self.class.serialization_scope :admin_user
- end
-
- def show
- render json: @post, serializer: PostSerializer
- end
-
- def edit
- @post.save
- render json: @post, serializer: Admin::PostSerializer
- end
-
- private
-
- def admin_user
- User.new(id: 2, name: 'Bob', admin: true)
- end
-
- def current_user
- User.new(id: 2, name: 'Bob', admin: false)
- end
-end
-```
-
-#### #read_attribute_for_serialization(key)
-
-The serialized value for a given key. e.g. `read_attribute_for_serialization(:title) #=> 'Hello World'`
-
-#### #links
-
-Allows you to modify the `links` node. By default, this node will be populated with the attributes set using the [::link](#link) method. Using `links: nil` will remove the `links` node.
-
-```ruby
-ActiveModelSerializers::SerializableResource.new(
- @post,
- adapter: :json_api,
- links: {
- self: {
- href: 'http://example.com/posts',
- meta: {
- stuff: 'value'
- }
- }
- }
-)
-```
-
-#### #json_key
-
-Returns the key used by the adapter as the resource root. See [root](#root) for more information.
-
-## Examples
-
-Given two models, a `Post(title: string, body: text)` and a
-`Comment(name: string, body: text, post_id: integer)`, you will have two
-serializers:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- cache key: 'posts', expires_in: 3.hours
- attributes :title, :body
-
- has_many :comments
-end
-```
-
-and
-
-```ruby
-class CommentSerializer < ActiveModel::Serializer
- attributes :name, :body
-
- belongs_to :post
-end
-```
-
-Generally speaking, you, as a user of ActiveModelSerializers, will write (or generate) these
-serializer classes.
-
-## More Info
-
-For more information, see [the Serializer class on GitHub](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model/serializer.rb)
-
-## Overriding association methods
-
-To override an association, call `has_many`, `has_one` or `belongs_to` with a block:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- has_many :comments do
- object.comments.active
- end
-end
-```
-
-## Overriding attribute methods
-
-To override an attribute, call `attribute` with a block:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attribute :body do
- object.body.downcase
- end
-end
-```
-
-## Overriding association serializer lookup
-
-If you want to define a specific serializer lookup for your associations, you can override
-the `ActiveModel::Serializer.serializer_for` method to return a serializer class based on defined conditions.
-
-```ruby
-class MySerializer < ActiveModel::Serializer
- def self.serializer_for(model, options)
- return SparseAdminSerializer if model.class == 'Admin'
- super
- end
-
- # the rest of the serializer
-end
-```
diff --git a/docs/how-open-source-maintained.jpg b/docs/how-open-source-maintained.jpg
deleted file mode 100644
index 7e4fa53a..00000000
Binary files a/docs/how-open-source-maintained.jpg and /dev/null differ
diff --git a/docs/howto/add_pagination_links.md b/docs/howto/add_pagination_links.md
deleted file mode 100644
index e2792383..00000000
--- a/docs/howto/add_pagination_links.md
+++ /dev/null
@@ -1,138 +0,0 @@
-[Back to Guides](../README.md)
-
-# How to add pagination links
-
-### JSON API adapter
-
-Pagination links will be included in your response automatically as long as
-the resource is paginated and if you are using the ```JsonApi``` adapter.
-
-If you want pagination links in your response, use [Kaminari](https://github.com/amatsuda/kaminari)
-or [WillPaginate](https://github.com/mislav/will_paginate).
-
-Although the other adapters do not have this feature, it is possible to
-implement pagination links to `JSON` adapter. For more information about it,
-please check our docs.
-
-###### Kaminari examples
-
-```ruby
-#array
-@posts = Kaminari.paginate_array([1, 2, 3]).page(3).per(1)
-render json: @posts
-
-#active_record
-@posts = Post.page(3).per(1)
-render json: @posts
-```
-
-###### WillPaginate examples
-
-```ruby
-#array
-@posts = [1,2,3].paginate(page: 3, per_page: 1)
-render json: @posts
-
-#active_record
-@posts = Post.page(3).per_page(1)
-render json: @posts
-```
-
-```ruby
-ActiveModelSerializers.config.adapter = :json_api
-```
-
-ex:
-```json
-{
- "data": [
- {
- "type": "articles",
- "id": "3",
- "attributes": {
- "title": "JSON API paints my bikeshed!",
- "body": "The shortest article. Ever.",
- "created": "2015-05-22T14:56:29.000Z",
- "updated": "2015-05-22T14:56:28.000Z"
- }
- }
- ],
- "links": {
- "self": "http://example.com/articles?page[number]=3&page[size]=1",
- "first": "http://example.com/articles?page[number]=1&page[size]=1",
- "prev": "http://example.com/articles?page[number]=2&page[size]=1",
- "next": "http://example.com/articles?page[number]=4&page[size]=1",
- "last": "http://example.com/articles?page[number]=13&page[size]=1"
- }
-}
-```
-
-ActiveModelSerializers pagination relies on a paginated collection with the methods `current_page`, `total_pages`, and `size`, such as are supported by both [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate).
-
-
-### JSON adapter
-
-If you are not using `JSON` adapter, pagination links will not be included automatically, but it is possible to do so using `meta` key.
-
-Add this method to your base API controller.
-
-```ruby
-def pagination_dict(collection)
- {
- current_page: collection.current_page,
- next_page: collection.next_page,
- prev_page: collection.prev_page, # use collection.previous_page when using will_paginate
- total_pages: collection.total_pages,
- total_count: collection.total_count
- }
-end
-```
-
-Then, use it on your render method.
-
-```ruby
-render json: posts, meta: pagination_dict(posts)
-```
-
-ex.
-```json
-{
- "posts": [
- {
- "id": 2,
- "title": "JSON API paints my bikeshed!",
- "body": "The shortest article. Ever."
- }
- ],
- "meta": {
- "current_page": 3,
- "next_page": 4,
- "prev_page": 2,
- "total_pages": 10,
- "total_count": 10
- }
-}
-```
-
-You can also achieve the same result if you have a helper method that adds the pagination info in the meta tag. For instance, in your action specify a custom serializer.
-
-```ruby
-render json: @posts, each_serializer: PostPreviewSerializer, meta: meta_attributes(@posts)
-```
-
-```ruby
-#expects pagination!
-def meta_attributes(collection, extra_meta = {})
- {
- current_page: collection.current_page,
- next_page: collection.next_page,
- prev_page: collection.prev_page, # use collection.previous_page when using will_paginate
- total_pages: collection.total_pages,
- total_count: collection.total_count
- }.merge(extra_meta)
-end
-```
-
-### Attributes adapter
-
-This adapter does not allow us to use `meta` key, due to that it is not possible to add pagination links.
diff --git a/docs/howto/add_relationship_links.md b/docs/howto/add_relationship_links.md
deleted file mode 100644
index ba8f7f8a..00000000
--- a/docs/howto/add_relationship_links.md
+++ /dev/null
@@ -1,140 +0,0 @@
-[Back to Guides](../README.md)
-
-# How to add relationship links
-
-ActiveModelSerializers offers you many ways to add links in your JSON, depending on your needs.
-The most common use case for links is supporting nested resources.
-
-The following examples are without included relationship data (`include` param is empty),
-specifically the following Rails controller was used for these examples:
-
-```ruby
-class Api::V1::UsersController < ApplicationController
- def show
- render jsonapi: User.find(params[:id]),
- serializer: Api::V1::UserSerializer,
- include: []
- end
-end
-```
-
-Bear in mind though that ActiveModelSerializers are [framework-agnostic](outside_controller_use.md), Rails is just a common example here.
-
-### Links as an attribute of a resource
-**This is applicable to JSON and Attributes adapters**
-
-You can define an attribute in the resource, named `links`.
-
-```ruby
-class Api::V1::UserSerializer < ActiveModel::Serializer
- include Rails.application.routes.url_helpers
-
- attributes :id, :name
-
- attribute :links do
- id = object.id
- {
- self: api_v1_user_path(id),
- microposts: api_v1_microposts_path(user_id: id)
- }
- end
-end
-```
-
-Using the `JSON` adapter, this will result in:
-
-```json
-{
- "user": {
- "id": "1",
- "name": "John",
- "links": {
- "self": "/api/v1/users/1",
- "microposts": "/api/v1/microposts?user_id=1"
- }
- }
-}
-```
-
-
-### Links as a property of the resource definiton
-**This is only applicable to JSONAPI adapter**
-
-You can use the `link` class method to define the links you need in the resource's primary data.
-
-```ruby
-class Api::V1::UserSerializer < ActiveModel::Serializer
- attributes :id, :name
-
- link(:self) { api_v1_user_path(object.id) }
- link(:microposts) { api_v1_microposts_path(user_id: object.id) }
-end
-```
-
-Using the `JSONAPI` adapter, this will result in:
-
-```json
-{
- "data": {
- "id": "1",
- "type": "users",
- "attributes": {
- "name": "Example User"
- },
- "links": {
- "self": "/api/v1/users/1",
- "microposts": "/api/v1/microposts?user_id=1"
- }
- }
-}
-```
-
-### Links that follow the JSONAPI spec
-**This is only applicable to JSONAPI adapter**
-
-If you have a JSONAPI-strict client that you are working with (like `ember-data`)
-you need to construct the links inside the relationships. Also the link to fetch the
-relationship data must be under the `related` attribute, whereas to manipulate the
-relationship (in case of many-to-many relationship) must be under the `self` attribute.
-
-You can find more info in the [spec](http://jsonapi.org/format/#document-resource-object-relationships).
-
-Here is how you can do this:
-
-```ruby
-class Api::V1::UserSerializer < ActiveModel::Serializer
- attributes :id, :name
-
- has_many :microposts, serializer: Api::V1::MicropostSerializer do
- link(:related) { api_v1_microposts_path(user_id: object.id) }
-
- microposts = object.microposts
- # The following code is needed to avoid n+1 queries.
- # Core devs are working to remove this necessity.
- # See: https://github.com/rails-api/active_model_serializers/issues/1325
- microposts.loaded? ? microposts : microposts.none
- end
-end
-```
-
-This will result in:
-
-```json
-{
- "data": {
- "id": "1",
- "type": "users",
- "attributes": {
- "name": "Example User"
- },
- "relationships": {
- "microposts": {
- "data": [],
- "links": {
- "related": "/api/v1/microposts?user_id=1"
- }
- }
- }
- }
-}
-```
diff --git a/docs/howto/add_root_key.md b/docs/howto/add_root_key.md
deleted file mode 100644
index 82a4ab6f..00000000
--- a/docs/howto/add_root_key.md
+++ /dev/null
@@ -1,55 +0,0 @@
-[Back to Guides](../README.md)
-
-# How to add root key
-
-Add the root key to your API is quite simple with ActiveModelSerializers. The **Adapter** is what determines the format of your JSON response. The default adapter is the ```Attributes``` which doesn't have the root key, so your response is something similar to:
-
-```json
-{
- "id": 1,
- "title": "Awesome Post Tile",
- "content": "Post content"
-}
-```
-
-In order to add the root key you need to use the ```JSON``` Adapter, you can change this in an initializer:
-
-```ruby
-ActiveModelSerializers.config.adapter = :json
-```
-
-You can also specify a class as adapter, as long as it complies with the ActiveModelSerializers adapters interface.
-It will add the root key to all your serialized endpoints.
-
-ex:
-
-```json
-{
- "post": {
- "id": 1,
- "title": "Awesome Post Tile",
- "content": "Post content"
- }
-}
-```
-
-or if it returns a collection:
-
-```json
-{
- "posts": [
- {
- "id": 1,
- "title": "Awesome Post Tile",
- "content": "Post content"
- },
- {
- "id": 2,
- "title": "Another Post Tile",
- "content": "Another post content"
- }
- ]
-}
-```
-
-[There are several ways to specify root](../general/serializers.md#root) when using the JSON adapter.
diff --git a/docs/howto/grape_integration.md b/docs/howto/grape_integration.md
deleted file mode 100644
index 9ff1353e..00000000
--- a/docs/howto/grape_integration.md
+++ /dev/null
@@ -1,42 +0,0 @@
-[Back to Guides](../README.md)
-
-The ActiveModelSerializers grape formatter relies on the existence of `env['grape.request']` which is implemeted by `Grape::Middleware::Globals`. You can meet his dependency by calling it before mounting the endpoints.
-
-In the simpliest way:
-
-```
-class API < Grape::API
- # @note Make sure this is above you're first +mount+
- use Grape::Middleware::Globals
-end
-```
-
-or more like what is shown in current Grape tutorials:
-
-```
-module MyApi
- class ApiBase < Grape::API
- use Grape::Middleware::Globals
-
- require 'grape/active_model_serializers'
- include Grape::ActiveModelSerializers
-
- mount MyApi::V1::ApiBase
- end
-end
-```
-
-You could meet this dependency with your own middleware. The invocation might look like:
-
-```
-module MyApi
- class ApiBase < Grape::API
- use My::Middleware::Thingamabob
-
- require 'grape/active_model_serializers'
- include Grape::ActiveModelSerializers
-
- mount MyApi::V1::ApiBase
- end
-end
-```
diff --git a/docs/howto/outside_controller_use.md b/docs/howto/outside_controller_use.md
deleted file mode 100644
index cb6d9b5e..00000000
--- a/docs/howto/outside_controller_use.md
+++ /dev/null
@@ -1,66 +0,0 @@
-[Back to Guides](../README.md)
-
-## Using ActiveModelSerializers Outside Of A Controller
-
-### Serializing a resource
-
-In ActiveModelSerializers versions 0.10 or later, serializing resources outside of the controller context is fairly simple:
-
-```ruby
-# Create our resource
-post = Post.create(title: "Sample post", body: "I love Active Model Serializers!")
-
-# Optional options parameters for both the serializer and instance
-options = {serializer: PostDetailedSerializer, username: 'sample user'}
-
-# Create a serializable resource instance
-serializable_resource = ActiveModelSerializers::SerializableResource.new(post, options)
-
-# Convert your resource into json
-model_json = serializable_resource.as_json
-```
-The object that is passed to `ActiveModelSerializers::SerializableResource.new` can be a single resource or a collection.
-The additional options are the same options that are passed [through controllers](../general/rendering.md#explicit-serializer).
-
-### Looking up the Serializer for a Resource
-
-If you want to retrieve the serializer class for a specific resource, you can do the following:
-
-```ruby
-# Create our resource
-post = Post.create(title: "Another Example", body: "So much fun.")
-
-# Optional options parameters
-options = {}
-
-# Retrieve the default serializer for posts
-serializer = ActiveModel::Serializer.serializer_for(post, options)
-```
-
-You could also retrieve the serializer via:
-
-```ruby
-ActiveModelSerializers::SerializableResource.new(post, options).serializer
-```
-
-Both approaches will return the serializer class that will be used for the resource.
-
-Additionally, you could retrieve the serializer instance for the resource via:
-
-```ruby
-ActiveModelSerializers::SerializableResource.new(post, options).serializer_instance
-```
-
-## Serializing before controller render
-
-At times, you might want to use a serializer without rendering it to the view. For those cases, you can create an instance of `ActiveModelSerializers::SerializableResource` with
-the resource you want to be serialized and call `.as_json`.
-
-```ruby
-def create
- message = current_user.messages.create!(message_params)
- message_json = ActiveModelSerializers::SerializableResource.new(message).as_json
- MessageCreationWorker.perform(message_json)
- head 204
-end
-```
diff --git a/docs/howto/passing_arbitrary_options.md b/docs/howto/passing_arbitrary_options.md
deleted file mode 100644
index 4e0fc9a0..00000000
--- a/docs/howto/passing_arbitrary_options.md
+++ /dev/null
@@ -1,27 +0,0 @@
-[Back to Guides](../README.md)
-
-# Passing Arbitrary Options To A Serializer
-
-In addition to the [`serialization_scope`](../general/serializers.md#scope), any options passed to `render`
-that are not reserved for the [adapter](../general/rendering.md#adapter_opts)
-are available in the serializer as [instance_options](../general/serializers.md#instance_options).
-
-For example, we could pass in a field, such as `user_id` into our serializer.
-
-```ruby
-# posts_controller.rb
-class PostsController < ApplicationController
- def dashboard
- render json: @post, user_id: 12
- end
-end
-
-# post_serializer.rb
-class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body
-
- def comments_by_me
- Comments.where(user_id: instance_options[:user_id], post_id: object.id)
- end
-end
-```
diff --git a/docs/howto/serialize_poro.md b/docs/howto/serialize_poro.md
deleted file mode 100644
index 3b98267c..00000000
--- a/docs/howto/serialize_poro.md
+++ /dev/null
@@ -1,73 +0,0 @@
-[Back to Guides](../README.md)
-
-# How to serialize a Plain-Old Ruby Object (PORO)
-
-When you are first getting started with ActiveModelSerializers, it may seem only `ActiveRecord::Base` objects can be serializable,
-but pretty much any object can be serializable with ActiveModelSerializers.
-Here is an example of a PORO that is serializable in most situations:
-
-```ruby
-# my_model.rb
-class MyModel
- alias :read_attribute_for_serialization :send
- attr_accessor :id, :name, :level
-
- def initialize(attributes)
- @id = attributes[:id]
- @name = attributes[:name]
- @level = attributes[:level]
- end
-
- def self.model_name
- @_model_name ||= ActiveModel::Name.new(self)
- end
-end
-```
-
-The [ActiveModel::Serializer::Lint::Tests](../../lib/active_model/serializer/lint.rb)
-define and validate which methods ActiveModelSerializers expects to be implemented.
-
-An implementation of the complete spec is included either for use or as reference:
-[`ActiveModelSerializers::Model`](../../lib/active_model_serializers/model.rb).
-You can use in production code that will make your PORO a lot cleaner.
-
-The above code now becomes:
-
-```ruby
-# my_model.rb
-class MyModel < ActiveModelSerializers::Model
- attributes :id, :name, :level
-end
-```
-
-The default serializer would be `MyModelSerializer`.
-
-*IMPORTANT*: There is a surprising behavior (bug) in the current implementation of ActiveModelSerializers::Model that
-prevents an accessor from modifying attributes on the instance. The fix for this bug
-is a breaking change, so we have made an opt-in configuration.
-
-New applications should set:
-
-```ruby
-ActiveModelSerializers::Model.derive_attributes_from_names_and_fix_accessors
-```
-
-Existing applications can use the fix *and* avoid breaking changes
-by making a superclass for new models. For example:
-
-```ruby
-class SerializablePoro < ActiveModelSerializers::Model
- derive_attributes_from_names_and_fix_accessors
-end
-```
-
-So that `MyModel` above would inherit from `SerializablePoro`.
-
-`derive_attributes_from_names_and_fix_accessors` prepends the `DeriveAttributesFromNamesAndFixAccessors`
-module and does the following:
-
-- `id` will *always* be in the attributes. (This is until we separate out the caching requirement for POROs.)
-- Overwrites the `attributes` method to that it only returns declared attributes.
- `attributes` will now be a frozen hash with indifferent access.
-
-For more information, see [README: What does a 'serializable resource' look like?](../../README.md#what-does-a-serializable-resource-look-like).
diff --git a/docs/howto/test.md b/docs/howto/test.md
deleted file mode 100644
index c66e0e9a..00000000
--- a/docs/howto/test.md
+++ /dev/null
@@ -1,154 +0,0 @@
-[Back to Guides](../README.md)
-
-# How to test
-
-## Controller Serializer Usage
-
-ActiveModelSerializers provides a `assert_serializer` method to be used on your controller tests to
-assert that a specific serializer was used.
-
-```ruby
-class PostsControllerTest < ActionController::TestCase
- test "should render post serializer" do
- get :index
- assert_serializer "PostSerializer"
- end
-end
-```
-
-See [ActiveModelSerializers::Test::Serializer](../../lib/active_model_serializers/test/serializer.rb)
-for more examples and documentation.
-
-## Serialization against a schema
-
-### Dependencies
-
-To use the `assert_response_schema` you need to have the
-[`json_schema`](https://github.com/brandur/json_schema) on your Gemfile. Please
-add it to your Gemfile and run `$ bundle install`.
-
-### Minitest test helpers
-
-ActiveModelSerializers provides a `assert_response_schema` method to be used on your controller tests to
-assert the response against a [JSON Schema](http://json-schema.org/). Let's take
-a look in an example.
-
-```ruby
-class PostsController < ApplicationController
- def show
- @post = Post.find(params[:id])
-
- render json: @post
- end
-end
-```
-
-To test the `posts#show` response of this controller we need to create a file
-named `test/support/schemas/posts/show.json`. The helper uses a naming convention
-to locate the file.
-
-This file is a JSON Schema representation of our response.
-
-```json
-{
- "properties": {
- "title" : { "type" : "string" },
- "content" : { "type" : "string" }
- }
-}
-```
-
-With all in place we can go to our test and use the helper.
-
-```ruby
-class PostsControllerTest < ActionController::TestCase
- test "should render right response" do
- get :index
- assert_response_schema
- end
-end
-```
-
-#### Load a custom schema
-
-If we need to use another schema, for example when we have a namespaced API that
-shows the same response, we can pass the path of the schema.
-
-```ruby
-module V1
- class PostsController < ApplicationController
- def show
- @post = Post.find(params[:id])
-
- render json: @post
- end
- end
-end
-```
-
-```ruby
-class V1::PostsControllerTest < ActionController::TestCase
- test "should render right response" do
- get :index
- assert_response_schema('posts/show.json')
- end
-end
-```
-
-#### Change the schema path
-
-By default all schemas are created at `test/support/schemas`. If we are using
-RSpec for example we can change this to `spec/support/schemas` defining the
-default schema path in an initializer.
-
-```ruby
-ActiveModelSerializers.config.schema_path = 'spec/support/schemas'
-```
-
-#### Using with the Heroku’s JSON Schema-based tools
-
-To use the test helper with the [prmd](https://github.com/interagent/prmd) and
-[committee](https://github.com/interagent/committee).
-
-We need to change the schema path to the recommended by prmd:
-
-```ruby
-ActiveModelSerializers.config.schema_path = 'docs/schema/schemata'
-```
-
-We also need to structure our schemata according to Heroku's conventions
-(e.g. including
-[required metadata](https://github.com/interagent/prmd/blob/master/docs/schemata.md#meta-data)
-and [links](https://github.com/interagent/prmd/blob/master/docs/schemata.md#links).
-
-#### JSON Pointers
-
-If we plan to use [JSON
-Pointers](http://spacetelescope.github.io/understanding-json-schema/UnderstandingJSONSchema.pdf) we need to define the `id` attribute on the schema. Example:
-
-```js
-// attributes.json
-
-{
- "id": "file://attributes.json#",
- "properties": {
- "name" : { "type" : "string" },
- "description" : { "type" : "string" }
- }
-}
-```
-
-```js
-// show.json
-
-{
- "properties": {
- "name": {
- "$ref": "file://attributes.json#/properties/name"
- },
- "description": {
- "$ref": "file://attributes.json#/properties/description"
- }
- }
-}
-```
diff --git a/docs/howto/upgrade_from_0_8_to_0_10.md b/docs/howto/upgrade_from_0_8_to_0_10.md
deleted file mode 100644
index ea51e81c..00000000
--- a/docs/howto/upgrade_from_0_8_to_0_10.md
+++ /dev/null
@@ -1,265 +0,0 @@
-[Back to Guides](../README.md)
-
-# How to migrate from `0.8` to `0.10` safely
-
-## Disclaimer
-### Proceed at your own risk
-This document attempts to outline steps to upgrade your app based on the collective experience of
-developers who have done this already. It may not cover all edge cases and situations that may cause issues,
-so please proceed with a certain level of caution.
-
-## Overview
-This document outlines the steps needed to migrate from `0.8` to `0.10`. The method described
-below has been created via the collective knowledge of contributions of those who have done
-the migration successfully. The method has been tested specifically for migrating from `0.8.3`
-to `0.10.2`.
-
-The high level approach is to upgrade to `0.10` and change all serializers to use
-a backwards-compatible `ActiveModel::V08::Serializer`or `ActiveModel::V08::CollectionSerializer`
-and a `ActiveModelSerializers::Adapter::V08Adapter`. After a few more manual changes, you should have the same
-functionality as you had with `AMS 0.8`. Then, you can continue to develop in your app by creating
-new serializers that don't use these backwards compatible versions and slowly migrate
-existing serializers to the `0.10` versions as needed.
-
-### `0.10` breaking changes
-- Passing a serializer to `render json:` is no longer supported
-
-```ruby
-render json: CustomerSerializer.new(customer) # rendered in 0.8, errors in 0.10
-```
-
-- Passing a nil resource to serializer now fails
-
-```ruby
-CustomerSerializer.new(nil) # returned nil in 0.8, throws error in 0.10
-```
-
-- Attribute methods are no longer defined on the serializer, and must be explicitly
- accessed through `object`
-
-```ruby
-class MySerializer
- attributes :foo, :bar
-
- def foo
- bar + 1 # bar does not work, needs to be object.bar in 0.10
- end
-end
-```
-
- - `root` option to collection serializer behaves differently
-
-```ruby
-# in 0.8
-ActiveModel::ArraySerializer.new(resources, root: "resources")
-# resulted in { "resources": }, does not work in 0.10
-```
-
-- No default serializer when serializer doesn't exist
-- `@options` changed to `instance_options`
-- Nested relationships are no longer walked by default. Use the `:include` option at **controller `render`** level to specify what relationships to walk. E.g. `render json: @post, include: {comments: :author}` if you want the `author` relationship walked, otherwise the json would only include the post with comments. See: https://github.com/rails-api/active_model_serializers/pull/1127
-- To emulate `0.8`'s walking of arbitrarily deep relationships use: `include: '**'`. E.g. `render json: @post, include: '**'`
-
-## Steps to migrate
-
-### 1. Upgrade the `active_model_serializer` gem in you `Gemfile`
-Change to `gem 'active_model_serializers', '~> 0.10'` and run `bundle install`
-
-### 2. Add `ActiveModel::V08::Serializer`
-
-```ruby
-module ActiveModel
- module V08
- class Serializer < ActiveModel::Serializer
- include Rails.application.routes.url_helpers
-
- # AMS 0.8 would delegate method calls from within the serializer to the
- # object.
- def method_missing(*args)
- method = args.first
- read_attribute_for_serialization(method)
- end
-
- alias_method :options, :instance_options
-
- # Since attributes could be read from the `object` via `method_missing`,
- # the `try` method did not behave as before. This patches `try` with the
- # original implementation plus the addition of
- # ` || object.respond_to?(a.first, true)` to check if the object responded to
- # the given method.
- def try(*a, &b)
- if a.empty? || respond_to?(a.first, true) || object.respond_to?(a.first, true)
- try!(*a, &b)
- end
- end
-
- # AMS 0.8 would return nil if the serializer was initialized with a nil
- # resource.
- def serializable_hash(adapter_options = nil,
- options = {},
- adapter_instance =
- self.class.serialization_adapter_instance)
- object.nil? ? nil : super
- end
- end
- end
-end
-
-```
-Add this class to your app however you see fit. This is the class that your existing serializers
-that inherit from `ActiveModel::Serializer` should inherit from.
-
-### 3. Add `ActiveModel::V08::CollectionSerializer`
-```ruby
-module ActiveModel
- module V08
- class CollectionSerializer < ActiveModel::Serializer::CollectionSerializer
- # In AMS 0.8, passing an ArraySerializer instance with a `root` option
- # properly nested the serialized resources within the given root.
- # Ex.
- #
- # class MyController < ActionController::Base
- # def index
- # render json: ActiveModel::Serializer::ArraySerializer
- # .new(resources, root: "resources")
- # end
- # end
- #
- # Produced
- #
- # {
- # "resources": [
- # ,
- # ...
- # ]
- # }
- def as_json(options = {})
- if root
- {
- root => super
- }
- else
- super
- end
- end
-
- # AMS 0.8 used `DefaultSerializer` if it couldn't find a serializer for
- # the given resource. When not using an adapter, this is not true in
- # `0.10`
- def serializer_from_resource(resource, serializer_context_class, options)
- serializer_class =
- options.fetch(:serializer) { serializer_context_class.serializer_for(resource) }
-
- if serializer_class.nil? # rubocop:disable Style/GuardClause
- DefaultSerializer.new(resource, options)
- else
- serializer_class.new(resource, options.except(:serializer))
- end
- end
-
- class DefaultSerializer
- attr_reader :object, :options
-
- def initialize(object, options={})
- @object, @options = object, options
- end
-
- def serializable_hash
- @object.as_json(@options)
- end
- end
- end
- end
-end
-```
-Add this class to your app however you see fit. This is the class that existing uses of
-`ActiveModel::ArraySerializer` should be changed to use.
-
-### 4. Add `ActiveModelSerializers::Adapter::V08Adapter`
-```ruby
-module ActiveModelSerializers
- module Adapter
- class V08Adapter < ActiveModelSerializers::Adapter::Base
- def serializable_hash(options = nil)
- options ||= {}
-
- if serializer.respond_to?(:each)
- if serializer.root
- delegate_to_json_adapter(options)
- else
- serializable_hash_for_collection(options)
- end
- else
- serializable_hash_for_single_resource(options)
- end
- end
-
- def serializable_hash_for_collection(options)
- serializer.map do |s|
- V08Adapter.new(s, instance_options)
- .serializable_hash(options)
- end
- end
-
- def serializable_hash_for_single_resource(options)
- if serializer.object.is_a?(ActiveModel::Serializer)
- # It is recommended that you add some logging here to indicate
- # places that should get converted to eventually allow for this
- # adapter to get removed.
- @serializer = serializer.object
- end
-
- if serializer.root
- delegate_to_json_adapter(options)
- else
- options = serialization_options(options)
- serializer.serializable_hash(instance_options, options, self)
- end
- end
-
- def delegate_to_json_adapter(options)
- ActiveModelSerializers::Adapter::Json
- .new(serializer, instance_options)
- .serializable_hash(options)
- end
- end
- end
-end
-```
-Add this class to your app however you see fit.
-
-Add
-```ruby
-ActiveModelSerializers.config.adapter =
- ActiveModelSerializers::Adapter::V08Adapter
-```
-to `config/active_model_serializer.rb` to configure AMS to use this
-class as the default adapter.
-
-### 5. Change inheritors of `ActiveModel::Serializer` to inherit from `ActiveModel::V08::Serializer`
-Simple find/replace
-
-### 6. Remove `private` keyword from serializers
-Simple find/replace. This is required to allow the `ActiveModel::V08::Serializer`
-to have proper access to the methods defined in the serializer.
-
-You may be able to change the `private` to `protected`, but this is hasn't been tested yet.
-
-### 7. Remove references to `ActiveRecord::Base#active_model_serializer`
-This method is no longer supported in `0.10`.
-
-`0.10` does a good job of discovering serializers for `ActiveRecord` objects.
-
-### 8. Rename `ActiveModel::ArraySerializer` to `ActiveModel::V08::CollectionSerializer`
-Find/replace uses of `ActiveModel::ArraySerializer` with `ActiveModel::V08::CollectionSerializer`.
-
-Also, be sure to change the `each_serializer` keyword to `serializer` when calling making the replacement.
-
-### 9. Replace uses of `@options` to `instance_options` in serializers
-Simple find/replace
-
-## Conclusion
-After you've done the steps above, you should test your app to ensure that everything is still working properly.
-
-If you run into issues, please contribute back to this document so others can benefit from your knowledge.
-
diff --git a/docs/integrations/ember-and-json-api.md b/docs/integrations/ember-and-json-api.md
deleted file mode 100644
index eb7f1ade..00000000
--- a/docs/integrations/ember-and-json-api.md
+++ /dev/null
@@ -1,147 +0,0 @@
-[Back to Guides](../README.md)
-
-# Integrating with Ember and JSON API
-
- - [Preparation](./ember-and-json-api.md#preparation)
- - [Server-Side Changes](./ember-and-json-api.md#server-side-changes)
- - [Adapter Changes](./ember-and-json-api.md#adapter-changes)
- - [Serializer Changes](./ember-and-json-api.md#serializer-changes)
- - [Including Nested Resources](./ember-and-json-api.md#including-nested-resources)
-
-## Preparation
-
-Note: This guide assumes that `ember-cli` is used for your ember app.
-
-The JSON API specification calls for hyphens for multi-word separators. ActiveModelSerializers uses underscores.
-To solve this, in Ember, both the adapter and the serializer will need some modifications:
-
-### Server-Side Changes
-
-First, set the adapter type in an initializer file:
-
-```ruby
-# config/initializers/active_model_serializers.rb
-ActiveModelSerializers.config.adapter = :json_api
-```
-
-or:
-
-```ruby
-# config/initializers/active_model_serializers.rb
-ActiveModelSerializers.config.adapter = ActiveModelSerializers::Adapter::JsonApi
-```
-
-You will also want to set the `key_transform` to `:unaltered` since you will adjust the attributes in your Ember serializer to use underscores instead of dashes later. You could also use `:underscore`, but `:unaltered` is better for performance.
-
-```ruby
-# config/initializers/active_model_serializers.rb
-ActiveModelSerializers.config.key_transform = :unaltered
-```
-
-In order to properly handle JSON API responses, we need to register a JSON API renderer, like so:
-
-```ruby
-# config/initializers/active_model_serializers.rb
-ActiveSupport.on_load(:action_controller) do
- require 'active_model_serializers/register_jsonapi_renderer'
-end
-```
-Rails also requires your controller to tell it that you accept and generate JSONAPI data. To do that, you use `respond_to` in your controller handlers to tell rails you are consuming and returning jsonapi format data. Without this, Rails will refuse to parse the request body into params. You can add `ActionController::MimeResponds` to your application controller to enable this:
-
-```ruby
-class ApplicationController < ActionController::API
- include ActionController::MimeResponds
-end
-```
-Then, in your controller you can tell rails you're accepting and rendering the jsonapi format:
-```ruby
- # POST /post
- def create
- @post = Post.new(post_params)
- respond_to do |format|
- if @post.save
- format.jsonapi { render jsonapi: @post, status: :created, location: @post }
- else
- format.jsonapi { render jsonapi: @post.errors, status: :unprocessable_entity }
- end
- end
- end
-
- # Only allow a trusted parameter "white list" through.
- def post_params
- ActiveModelSerializers::Deserialization.jsonapi_parse!(params, only: [:title, :body] )
- end
-end
-```
-
-#### Note:
-In Rails 5, the "unsafe" method ( `jsonapi_parse!` vs the safe `jsonapi_parse`) throws an `InvalidDocument` exception when the payload does not meet basic criteria for JSON API deserialization.
-
-
-### Adapter Changes
-
-```javascript
-// app/adapters/application.js
-import Ember from 'ember';
-import DS from 'ember-data';
-import ENV from "../config/environment";
-const { underscore, pluralize } = Ember.String;
-
-export default DS.JSONAPIAdapter.extend({
- namespace: 'api',
- // if your rails app is on a different port from your ember app
- // this can be helpful for development.
- // in production, the host for both rails and ember should be the same.
- host: ENV.host,
-
- // allows the multiword paths in urls to be underscored
- pathForType: function(type) {
- let underscored = underscore(type);
- return pluralize(underscored);
- },
-
-});
-```
-
-### Serializer Changes
-
-```javascript
-// app/serializers/application.js
-import Ember from 'ember';
-import DS from 'ember-data';
-var underscore = Ember.String.underscore;
-
-export default DS.JSONAPISerializer.extend({
- keyForAttribute: function(attr) {
- return underscore(attr);
- },
-
- keyForRelationship: function(rawKey) {
- return underscore(rawKey);
- }
-});
-
-```
-
-
-## Including Nested Resources
-
-Ember Data can request related records by using `include`. Below are some examples of how to make Ember Data request the inclusion of related records. For more on `include` usage, see: [The JSON API include examples](./../general/adapters.md#JSON-API)
-
-```javascript
-store.findRecord('post', postId, { include: 'comments' } );
-```
-which will generate the path /posts/{postId}?include='comments'
-
-So then in your controller, you'll want to be sure to have something like:
-```ruby
-render jsonapi: @post, include: params[:include]
-```
-
-If you want to use `include` on a collection, you'd write something like this:
-
-```javascript
-store.query('post', { include: 'comments' });
-```
-
-which will generate the path `/posts?include='comments'`
diff --git a/docs/integrations/grape.md b/docs/integrations/grape.md
deleted file mode 100644
index 7c855ebf..00000000
--- a/docs/integrations/grape.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Integration with Grape
-
-[Grape](https://github.com/ruby-grape/grape) is an opinionated micro-framework for creating REST-like APIs in ruby.
-
-ActiveModelSerializers currently supports Grape >= 0.13, < 1.0
-
-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:
-
-```ruby
-module Example
- class Dummy < Grape::API
- require 'grape/active_model_serializers'
- include Grape::ActiveModelSerializers
- mount Example::V1::Base
- end
-end
-```
-
-Aside from this, [configuration](../general/configuration_options.md) of ActiveModelSerializers is exactly the same.
diff --git a/docs/jsonapi/errors.md b/docs/jsonapi/errors.md
deleted file mode 100644
index d19e2f9c..00000000
--- a/docs/jsonapi/errors.md
+++ /dev/null
@@ -1,56 +0,0 @@
-[Back to Guides](../README.md)
-
-# [JSON API Errors](http://jsonapi.org/format/#errors)
-
-Rendering error documents requires specifying the error serializer(s):
-
-- Serializer:
- - For a single resource: `serializer: ActiveModel::Serializer::ErrorSerializer`.
- - For a collection: `serializer: ActiveModel::Serializer::ErrorsSerializer`, `each_serializer: ActiveModel::Serializer::ErrorSerializer`.
-
-The resource **MUST** have a non-empty associated `#errors` object.
-The `errors` object must have a `#messages` method that returns a hash of error name to array of
-descriptions.
-
-## Use in controllers
-
-```ruby
-resource = Profile.new(name: 'Name 1',
- description: 'Description 1',
- comments: 'Comments 1')
-resource.errors.add(:name, 'cannot be nil')
-resource.errors.add(:name, 'must be longer')
-resource.errors.add(:id, 'must be a uuid')
-
-render json: resource, status: 422, adapter: :json_api, serializer: ActiveModel::Serializer::ErrorSerializer
-# #=>
-# { :errors =>
-# [
-# { :source => { :pointer => '/data/attributes/name' }, :detail => 'cannot be nil' },
-# { :source => { :pointer => '/data/attributes/name' }, :detail => 'must be longer' },
-# { :source => { :pointer => '/data/attributes/id' }, :detail => 'must be a uuid' }
-# ]
-# }.to_json
-```
-
-## Direct error document generation
-
-```ruby
-options = nil
-resource = ModelWithErrors.new
-resource.errors.add(:name, 'must be awesome')
-
-serializable_resource = ActiveModelSerializers::SerializableResource.new(
- resource, {
- serializer: ActiveModel::Serializer::ErrorSerializer,
- adapter: :json_api
- })
-serializable_resource.as_json(options)
-# #=>
-# {
-# :errors =>
-# [
-# { :source => { :pointer => '/data/attributes/name' }, :detail => 'must be awesome' }
-# ]
-# }
-```
diff --git a/docs/jsonapi/schema.md b/docs/jsonapi/schema.md
deleted file mode 100644
index baffe358..00000000
--- a/docs/jsonapi/schema.md
+++ /dev/null
@@ -1,151 +0,0 @@
-[Back to Guides](../README.md)
-
-[](http://jsonapi.org/)
-
-## JSON API Requests
-
-- [Query Parameters Spec](http://jsonapi.org/format/#query-parameters)
-
-Headers:
-
-- Request: `Accept: application/vnd.api+json`
-- Response: `Content-Type: application/vnd.api+json`
-
-### [Fetching Data](http://jsonapi.org/format/#fetching)
-
-A server MUST support fetching resource data for every URL provided as:
-
-- a `self` link as part of the top-level links object
-- a `self` link as part of a resource-level links object
-- a `related` link as part of a relationship-level links object
-
-Example supported requests
-
-- Individual resource or collection
- - GET /articles
- - GET /articles/1
- - GET /articles/1/author
-- Relationships
- - GET /articles/1/relationships/comments
- - GET /articles/1/relationships/author
-- Optional: [Inclusion of related resources](http://jsonapi.org/format/#fetching-includes) `JSONAPI::IncludeDirective`
- - GET /articles/1?`include`=comments
- - GET /articles/1?`include`=comments.author
- - GET /articles/1?`include`=author,comments.author
- - GET /articles/1/relationships/comments?`include`=comments.author
-- Optional: [Sparse Fieldsets](http://jsonapi.org/format/#fetching-sparse-fieldsets) `ActiveModel::Serializer::Fieldset`
- - GET /articles?`include`=author&`fields`[articles]=title,body&`fields`[people]=name
-- Optional: [Sorting](http://jsonapi.org/format/#fetching-sorting)
- - GET /people?`sort`=age
- - GET /people?`sort`=age,author.name
- - GET /articles?`sort`=-created,title
-- Optional: [Pagination](http://jsonapi.org/format/#fetching-pagination)
- - GET /articles?`page`[number]=3&`page`[size]=1
-- Optional: [Filtering](http://jsonapi.org/format/#fetching-filtering)
- - GET /comments?`filter`[post]=1
- - GET /comments?`filter`[post]=1,2
- - GET /comments?`filter`[post]=1,2
-
-### [CRUD Actions](http://jsonapi.org/format/#crud)
-
-### [Asynchronous Processing](http://jsonapi.org/recommendations/#asynchronous-processing)
-
-### [Bulk Operations Extension](http://jsonapi.org/extensions/bulk/)
-
-## JSON API Document Schema
-
-| JSON API object | JSON API properties | Required | ActiveModelSerializers representation |
-|-----------------------|----------------------------------------------------------------------------------------------------|----------|---------------------------------------|
-| schema | oneOf (success, failure, info) | |
-| success | data, included, meta, links, jsonapi | | AM::SerializableResource
-| success.meta | meta | | AMS::Adapter::Base#meta
-| success.included | UniqueArray(resource) | | AMS::Adapter::JsonApi#serializable_hash_for_collection
-| success.data | data | |
-| success.links | allOf (links, pagination) | | AMS::Adapter::JsonApi#links_for
-| success.jsonapi | jsonapi | |
-| failure | errors, meta, jsonapi | errors | AMS::Adapter::JsonApi#failure_document, #1004
-| failure.errors | UniqueArray(error) | | AM::S::ErrorSerializer, #1004
-| meta | Object | |
-| data | oneOf (resource, UniqueArray(resource)) | | AMS::Adapter::JsonApi#serializable_hash_for_collection,#serializable_hash_for_single_resource
-| resource | String(type), String(id),
attributes, relationships,
links, meta | type, id | AM::S::Adapter::JsonApi#primary_data_for
-| links | Uri(self), Link(related) | | #1028, #1246, #1282
-| link | oneOf (linkString, linkObject) | |
-| link.linkString | Uri | |
-| link.linkObject | Uri(href), meta | href |
-| attributes | patternProperties(
`"^(?!relationships$|links$)\\w[-\\w_]*$"`),
any valid JSON | | AM::Serializer#attributes, AMS::Adapter::JsonApi#resource_object_for
-| relationships | patternProperties(
`"^\\w[-\\w_]*$"`);
links, relationships.data, meta | | AMS::Adapter::JsonApi#relationships_for
-| relationships.data | oneOf (relationshipToOne, relationshipToMany) | | AMS::Adapter::JsonApi#resource_identifier_for
-| relationshipToOne | anyOf(empty, linkage) | |
-| relationshipToMany | UniqueArray(linkage) | |
-| empty | null | |
-| linkage | String(type), String(id), meta | type, id | AMS::Adapter::JsonApi#primary_data_for
-| pagination | pageObject(first), pageObject(last),
pageObject(prev), pageObject(next) | | AMS::Adapter::JsonApi::PaginationLinks#serializable_hash
-| pagination.pageObject | oneOf(Uri, null) | |
-| jsonapi | String(version), meta | | AMS::Adapter::JsonApi::Jsonapi#as_json
-| error | String(id), links, String(status),
String(code), String(title),
String(detail), error.source, meta | | AM::S::ErrorSerializer, AMS::Adapter::JsonApi::Error.resource_errors
-| error.source | String(pointer), String(parameter) | | AMS::Adapter::JsonApi::Error.error_source
-| pointer | [JSON Pointer RFC6901](https://tools.ietf.org/html/rfc6901) | | AMS::JsonPointer
-
-
-The [http://jsonapi.org/schema](schema/schema.json) makes a nice roadmap.
-
-### Success Document
-- [ ] success
- - [ ] data: `"$ref": "#/definitions/data"`
- - [ ] included: array of unique items of type `"$ref": "#/definitions/resource"`
- - [ ] meta: `"$ref": "#/definitions/meta"`
- - [ ] links:
- - [ ] link: `"$ref": "#/definitions/links"`
- - [ ] pagination: ` "$ref": "#/definitions/pagination"`
- - [ ] jsonapi: ` "$ref": "#/definitions/jsonapi"`
-
-### Failure Document
-
-- [ ] failure
- - [x] errors: array of unique items of type ` "$ref": "#/definitions/error"`
- - [ ] meta: `"$ref": "#/definitions/meta"`
- - [ ] jsonapi: `"$ref": "#/definitions/jsonapi"`
-
-### Info Document
-
-- [ ] info
- - [ ] meta: `"$ref": "#/definitions/meta"`
- - [ ] links: `"$ref": "#/definitions/links"`
- - [ ] jsonapi: ` "$ref": "#/definitions/jsonapi"`
-
-### Definitions
-
-- [ ] definitions:
- - [ ] meta
- - [ ] data: oneOf (resource, array of unique resources)
- - [ ] resource
- - [ ] attributes
- - [ ] relationships
- - [ ] relationshipToOne
- - [ ] empty
- - [ ] linkage
- - [ ] meta
- - [ ] relationshipToMany
- - [ ] linkage
- - [ ] meta
- - [ ] links
- - [ ] meta
- - [ ] links
- - [ ] link
- - [ ] uri
- - [ ] href, meta
- - [ ] pagination
- - [ ] jsonapi
- - [ ] meta
- - [ ] error
- - [ ] id: a unique identifier for this particular occurrence of the problem.
- - [ ] links: a links object containing the following members:
- - [ ] about: a link that leads to further details about this particular occurrence of the problem.
- - [ ] status: the HTTP status code applicable to this problem, expressed as a string value.
- - [ ] code: an application-specific error code, expressed as a string value.
- - [ ] title: a short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.
- - [x] detail: a human-readable explanation specific to this occurrence of the problem.
- - [x] source: an object containing references to the source of the error, optionally including any of the following members:
- - [x] pointer: a JSON Pointer [RFC6901](https://tools.ietf.org/html/rfc6901) to the associated entity in the request document [e.g. "/data" for a primary data object, or "/data/attributes/title" for a specific attribute].
- - [x] parameter: a string indicating which query parameter caused the error.
- - [ ] meta: a meta object containing non-standard meta-information about the error.
diff --git a/docs/jsonapi/schema/schema.json b/docs/jsonapi/schema/schema.json
deleted file mode 100644
index ef3ea351..00000000
--- a/docs/jsonapi/schema/schema.json
+++ /dev/null
@@ -1,366 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-04/schema#",
- "title": "JSON API Schema",
- "description": "This is a schema for responses in the JSON API format. For more, see http://jsonapi.org",
- "oneOf": [
- {
- "$ref": "#/definitions/success"
- },
- {
- "$ref": "#/definitions/failure"
- },
- {
- "$ref": "#/definitions/info"
- }
- ],
-
- "definitions": {
- "success": {
- "type": "object",
- "required": [
- "data"
- ],
- "properties": {
- "data": {
- "$ref": "#/definitions/data"
- },
- "included": {
- "description": "To reduce the number of HTTP requests, servers **MAY** allow responses that include related resources along with the requested primary resources. Such responses are called \"compound documents\".",
- "type": "array",
- "items": {
- "$ref": "#/definitions/resource"
- },
- "uniqueItems": true
- },
- "meta": {
- "$ref": "#/definitions/meta"
- },
- "links": {
- "description": "Link members related to the primary data.",
- "allOf": [
- {
- "$ref": "#/definitions/links"
- },
- {
- "$ref": "#/definitions/pagination"
- }
- ]
- },
- "jsonapi": {
- "$ref": "#/definitions/jsonapi"
- }
- },
- "additionalProperties": false
- },
- "failure": {
- "type": "object",
- "required": [
- "errors"
- ],
- "properties": {
- "errors": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/error"
- },
- "uniqueItems": true
- },
- "meta": {
- "$ref": "#/definitions/meta"
- },
- "jsonapi": {
- "$ref": "#/definitions/jsonapi"
- }
- },
- "additionalProperties": false
- },
- "info": {
- "type": "object",
- "required": [
- "meta"
- ],
- "properties": {
- "meta": {
- "$ref": "#/definitions/meta"
- },
- "links": {
- "$ref": "#/definitions/links"
- },
- "jsonapi": {
- "$ref": "#/definitions/jsonapi"
- }
- },
- "additionalProperties": false
- },
-
- "meta": {
- "description": "Non-standard meta-information that can not be represented as an attribute or relationship.",
- "type": "object",
- "additionalProperties": true
- },
- "data": {
- "description": "The document's \"primary data\" is a representation of the resource or collection of resources targeted by a request.",
- "oneOf": [
- {
- "$ref": "#/definitions/resource"
- },
- {
- "description": "An array of resource objects, an array of resource identifier objects, or an empty array ([]), for requests that target resource collections.",
- "type": "array",
- "items": {
- "$ref": "#/definitions/resource"
- },
- "uniqueItems": true
- }
- ]
- },
- "resource": {
- "description": "\"Resource objects\" appear in a JSON API document to represent resources.",
- "type": "object",
- "required": [
- "type",
- "id"
- ],
- "properties": {
- "type": {
- "type": "string"
- },
- "id": {
- "type": "string"
- },
- "attributes": {
- "$ref": "#/definitions/attributes"
- },
- "relationships": {
- "$ref": "#/definitions/relationships"
- },
- "links": {
- "$ref": "#/definitions/links"
- },
- "meta": {
- "$ref": "#/definitions/meta"
- }
- },
- "additionalProperties": false
- },
-
- "links": {
- "description": "A resource object **MAY** contain references to other resource objects (\"relationships\"). Relationships may be to-one or to-many. Relationships can be specified by including a member in a resource's links object.",
- "type": "object",
- "properties": {
- "self": {
- "description": "A `self` member, whose value is a URL for the relationship itself (a \"relationship URL\"). This URL allows the client to directly manipulate the relationship. For example, it would allow a client to remove an `author` from an `article` without deleting the people resource itself.",
- "type": "string",
- "format": "uri"
- },
- "related": {
- "$ref": "#/definitions/link"
- }
- },
- "additionalProperties": true
- },
- "link": {
- "description": "A link **MUST** be represented as either: a string containing the link's URL or a link object.",
- "oneOf": [
- {
- "description": "A string containing the link's URL.",
- "type": "string",
- "format": "uri"
- },
- {
- "type": "object",
- "required": [
- "href"
- ],
- "properties": {
- "href": {
- "description": "A string containing the link's URL.",
- "type": "string",
- "format": "uri"
- },
- "meta": {
- "$ref": "#/definitions/meta"
- }
- }
- }
- ]
- },
-
- "attributes": {
- "description": "Members of the attributes object (\"attributes\") represent information about the resource object in which it's defined.",
- "type": "object",
- "patternProperties": {
- "^(?!relationships$|links$)\\w[-\\w_]*$": {
- "description": "Attributes may contain any valid JSON value."
- }
- },
- "additionalProperties": false
- },
-
- "relationships": {
- "description": "Members of the relationships object (\"relationships\") represent references from the resource object in which it's defined to other resource objects.",
- "type": "object",
- "patternProperties": {
- "^\\w[-\\w_]*$": {
- "properties": {
- "links": {
- "$ref": "#/definitions/links"
- },
- "data": {
- "description": "Member, whose value represents \"resource linkage\".",
- "oneOf": [
- {
- "$ref": "#/definitions/relationshipToOne"
- },
- {
- "$ref": "#/definitions/relationshipToMany"
- }
- ]
- },
- "meta": {
- "$ref": "#/definitions/meta"
- }
- },
- "additionalProperties": false
- }
- },
- "additionalProperties": false
- },
- "relationshipToOne": {
- "description": "References to other resource objects in a to-one (\"relationship\"). Relationships can be specified by including a member in a resource's links object.",
- "anyOf": [
- {
- "$ref": "#/definitions/empty"
- },
- {
- "$ref": "#/definitions/linkage"
- }
- ]
- },
- "relationshipToMany": {
- "description": "An array of objects each containing \"type\" and \"id\" members for to-many relationships.",
- "type": "array",
- "items": {
- "$ref": "#/definitions/linkage"
- },
- "uniqueItems": true
- },
- "empty": {
- "description": "Describes an empty to-one relationship.",
- "type": "null"
- },
- "linkage": {
- "description": "The \"type\" and \"id\" to non-empty members.",
- "type": "object",
- "required": [
- "type",
- "id"
- ],
- "properties": {
- "type": {
- "type": "string"
- },
- "id": {
- "type": "string"
- },
- "meta": {
- "$ref": "#/definitions/meta"
- }
- },
- "additionalProperties": false
- },
- "pagination": {
- "type": "object",
- "properties": {
- "first": {
- "description": "The first page of data",
- "oneOf": [
- { "type": "string", "format": "uri" },
- { "type": "null" }
- ]
- },
- "last": {
- "description": "The last page of data",
- "oneOf": [
- { "type": "string", "format": "uri" },
- { "type": "null" }
- ]
- },
- "prev": {
- "description": "The previous page of data",
- "oneOf": [
- { "type": "string", "format": "uri" },
- { "type": "null" }
- ]
- },
- "next": {
- "description": "The next page of data",
- "oneOf": [
- { "type": "string", "format": "uri" },
- { "type": "null" }
- ]
- }
- }
- },
-
- "jsonapi": {
- "description": "An object describing the server's implementation",
- "type": "object",
- "properties": {
- "version": {
- "type": "string"
- },
- "meta": {
- "$ref": "#/definitions/meta"
- }
- },
- "additionalProperties": false
- },
-
- "error": {
- "type": "object",
- "properties": {
- "id": {
- "description": "A unique identifier for this particular occurrence of the problem.",
- "type": "string"
- },
- "links": {
- "$ref": "#/definitions/links"
- },
- "status": {
- "description": "The HTTP status code applicable to this problem, expressed as a string value.",
- "type": "string"
- },
- "code": {
- "description": "An application-specific error code, expressed as a string value.",
- "type": "string"
- },
- "title": {
- "description": "A short, human-readable summary of the problem. It **SHOULD NOT** change from occurrence to occurrence of the problem, except for purposes of localization.",
- "type": "string"
- },
- "detail": {
- "description": "A human-readable explanation specific to this occurrence of the problem.",
- "type": "string"
- },
- "source": {
- "type": "object",
- "properties": {
- "pointer": {
- "description": "A JSON Pointer [RFC6901] to the associated entity in the request document [e.g. \"/data\" for a primary data object, or \"/data/attributes/title\" for a specific attribute].",
- "type": "string"
- },
- "parameter": {
- "description": "A string indicating which query parameter caused the error.",
- "type": "string"
- }
- }
- },
- "meta": {
- "$ref": "#/definitions/meta"
- }
- },
- "additionalProperties": false
- }
- }
-}
diff --git a/docs/rfcs/0000-namespace.md b/docs/rfcs/0000-namespace.md
deleted file mode 100644
index da07c4c1..00000000
--- a/docs/rfcs/0000-namespace.md
+++ /dev/null
@@ -1,106 +0,0 @@
-- Start Date: (2015-10-29)
-- RFC PR: https://github.com/rails-api/active_model_serializers/pull/1310
-- ActiveModelSerializers Issue: https://github.com/rails-api/active_model_serializers/issues/1298
-
-# Summary
-
-Provide a consistent API for the user of the AMS.
-
-# Motivation
-
-The actual public API is defined under `ActiveModelSerializers`,
-`ActiveModel::Serializer` and `ActiveModel`.
-
-At the `ActiveModel::Serializer` we have:
-
-- `ActiveModel::Serializer.config`
-- `ActiveModel::Serializer`
-
-At the `ActiveModelSerializers` we have:
-
-- `ActiveModelSerializers::Model`
-- `ActiveModelSerializers.logger`
-
-At `ActiveModel` we have:
-
-- `ActiveModel::SerializableResource`
-
-The idea here is to provide a single namespace `ActiveModelSerializers` to the user.
-Following the same idea we have on other gems like
-[Devise](https://github.com/plataformatec/devise/blob/e9c82472ffe7c43a448945f77e034a0e47dde0bb/lib/devise.rb),
-[Refile](https://github.com/refile/refile/blob/6b24c293d044862dafbf1bfa4606672a64903aa2/lib/refile.rb) and
-[Active Job](https://github.com/rails/rails/blob/30bacc26f8f258b39e12f63fe52389a968d9c1ea/activejob/lib/active_job.rb)
-for example.
-
-This way we are clarifing the boundaries of
-[ActiveModelSerializers and Rails](https://github.com/rails-api/active_model_serializers/blob/master/CHANGELOG.md#prehistory)
-and make clear that the `ActiveModel::Serializer` class is no longer the primary
-behavior of the ActiveModelSerializers.
-
-# Detailed design
-
-## New classes and modules organization
-
-Since this will be a big change we can do this on baby steps, read small pull requests. A
-possible approach is:
-
-- All new code will be in `lib/active_model_serializers/` using
- the module namespace `ActiveModelSerializers`.
-- Move all content under `ActiveModel::Serializer` to be under
- `ActiveModelSerializers`, the adapter is on this steps;
-- Move all content under `ActiveModel` to be under `ActiveModelSerializers`,
- the `SerializableResource` is on this step;
-- Change all public API that doesn't make sense, keeping in mind only to keep
- this in the same namespace
-- Update the README;
-- Update the docs;
-
-The following table represents the current and the desired classes and modules
-at the first moment.
-
-| Current | Desired | Notes |
-|--------------------------------------------------------|--------------------------------------------------|--------------------|
-| `ActiveModelSerializers` and `ActiveModel::Serializer` | `ActiveModelSerializers` | The main namespace |
-| `ActiveModelSerializers.logger` | `ActiveModelSerializers.logger` ||
-| `ActiveModelSerializers::Model` | `ActiveModelSerializers::Model` ||
-| `ActiveModel::SerializableResource` | `ActiveModelSerializers::SerializableResource` ||
-| `ActiveModel::Serializer` | `ActiveModelSerializers::Serializer` | The name can be discussed in a future pull request. For example, we can rename this to `Resource` [following this idea](https://github.com/rails-api/active_model_serializers/pull/1301/files#r42963185) more info about naming in the next section|
-| `ActiveModel::Serializer.config` | `ActiveModelSerializers.config` ||
-
-## Renaming of class and modules
-
-When moving some content to the new namespace we can find some names that does
-not make much sense like `ActiveModel::Serializer::Adapter::JsonApi`.
-Discussion of renaming existing classes / modules and JsonApi objects will
-happen in separate pull requests, and issues, and in the google doc
-https://docs.google.com/document/d/1rcrJr0sVcazY2Opd_6Kmv1iIwuHbI84s1P_NzFn-05c/edit?usp=sharing
-
-Some of names already have a definition.
-
-- Adapters get their own namespace under ActiveModelSerializers. E.g
- `ActiveModelSerializers::Adapter`
-- Serializers get their own namespace under ActiveModelSerializers. E.g
- `ActiveModelSerializers::Serializer`
-
-## Keeping compatibility
-
-All moved classes or modules be aliased to their old name and location with
-deprecation warnings, such as
-[was done for CollectionSerializer](https://github.com/rails-api/active_model_serializers/pull/1251).
-
-# Drawbacks
-
-This will be a breaking change, so all users serializers will be broken after a
-major bump.
-All pull requests will need to rebase since the architeture will change a lot.
-
-# Alternatives
-
-We can keep the way it is, and keep in mind to not add another namespace as a
-public API.
-
-# Unresolved questions
-
-What is the better class name to be used to the class that will be inherited at
-the creation of a serializer. This can be discussed in other RFC or directly via
-pull request.
diff --git a/lib/action_controller/serialization.rb b/lib/action_controller/serialization.rb
deleted file mode 100644
index ea84c674..00000000
--- a/lib/action_controller/serialization.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-require 'active_support/core_ext/class/attribute'
-require 'active_model_serializers/serialization_context'
-
-module ActionController
- module Serialization
- extend ActiveSupport::Concern
-
- include ActionController::Renderers
-
- module ClassMethods
- def serialization_scope(scope)
- self._serialization_scope = scope
- end
- end
-
- included do
- class_attribute :_serialization_scope
- self._serialization_scope = :current_user
-
- attr_writer :namespace_for_serializer
- end
-
- def namespace_for_serializer
- @namespace_for_serializer ||= self.class.parent unless self.class.parent == Object
- end
-
- def serialization_scope
- return unless _serialization_scope && respond_to?(_serialization_scope, true)
-
- send(_serialization_scope)
- end
-
- def get_serializer(resource, options = {})
- unless use_adapter?
- warn 'ActionController::Serialization#use_adapter? has been removed. '\
- "Please pass 'adapter: false' or see ActiveSupport::SerializableResource.new"
- options[:adapter] = false
- end
-
- options.fetch(:namespace) { options[:namespace] = namespace_for_serializer }
-
- serializable_resource = ActiveModelSerializers::SerializableResource.new(resource, options)
- serializable_resource.serialization_scope ||= options.fetch(:scope) { serialization_scope }
- serializable_resource.serialization_scope_name = options.fetch(:scope_name) { _serialization_scope }
- # For compatibility with the JSON renderer: `json.to_json(options) if json.is_a?(String)`.
- # Otherwise, since `serializable_resource` is not a string, the renderer would call
- # `to_json` on a String and given odd results, such as `"".to_json #=> '""'`
- serializable_resource.adapter.is_a?(String) ? serializable_resource.adapter : serializable_resource
- end
-
- # Deprecated
- def use_adapter?
- true
- end
-
- [:_render_option_json, :_render_with_renderer_json].each do |renderer_method|
- define_method renderer_method do |resource, options|
- options.fetch(:serialization_context) do
- options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request, options)
- end
- serializable_resource = get_serializer(resource, options)
- super(serializable_resource, options)
- end
- end
- end
-end
diff --git a/lib/active_model/serializable_resource.rb b/lib/active_model/serializable_resource.rb
deleted file mode 100644
index 0e1c8e2d..00000000
--- a/lib/active_model/serializable_resource.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require 'set'
-
-module ActiveModel
- class SerializableResource
- class << self
- extend ActiveModelSerializers::Deprecate
-
- delegate_and_deprecate :new, ActiveModelSerializers::SerializableResource
- end
- end
-end
diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb
deleted file mode 100644
index 9d00e6fb..00000000
--- a/lib/active_model/serializer.rb
+++ /dev/null
@@ -1,409 +0,0 @@
-require 'thread_safe'
-require 'jsonapi/include_directive'
-require 'active_model/serializer/collection_serializer'
-require 'active_model/serializer/array_serializer'
-require 'active_model/serializer/error_serializer'
-require 'active_model/serializer/errors_serializer'
-require 'active_model/serializer/concerns/caching'
-require 'active_model/serializer/fieldset'
-require 'active_model/serializer/lint'
-
-# ActiveModel::Serializer is an abstract class that is
-# reified when subclassed to decorate a resource.
-module ActiveModel
- class Serializer
- undef_method :select, :display # These IO methods, which are mixed into Kernel,
- # sometimes conflict with attribute names. We don't need these IO methods.
-
- # @see #serializable_hash for more details on these valid keys.
- SERIALIZABLE_HASH_VALID_KEYS = [:only, :except, :methods, :include, :root].freeze
- extend ActiveSupport::Autoload
- autoload :Adapter
- autoload :Null
- autoload :Attribute
- autoload :Association
- autoload :Reflection
- autoload :SingularReflection
- autoload :CollectionReflection
- autoload :BelongsToReflection
- autoload :HasOneReflection
- autoload :HasManyReflection
- include ActiveSupport::Configurable
- include Caching
-
- # @param resource [ActiveRecord::Base, ActiveModelSerializers::Model]
- # @return [ActiveModel::Serializer]
- # Preferentially returns
- # 1. resource.serializer_class
- # 2. ArraySerializer when resource is a collection
- # 3. options[:serializer]
- # 4. lookup serializer when resource is a Class
- def self.serializer_for(resource_or_class, options = {})
- if resource_or_class.respond_to?(:serializer_class)
- resource_or_class.serializer_class
- elsif resource_or_class.respond_to?(:to_ary)
- config.collection_serializer
- else
- resource_class = resource_or_class.class == Class ? resource_or_class : resource_or_class.class
- options.fetch(:serializer) { get_serializer_for(resource_class, options[:namespace]) }
- end
- end
-
- # @see ActiveModelSerializers::Adapter.lookup
- # Deprecated
- def self.adapter
- ActiveModelSerializers::Adapter.lookup(config.adapter)
- end
- class << self
- extend ActiveModelSerializers::Deprecate
- deprecate :adapter, 'ActiveModelSerializers::Adapter.configured_adapter'
- end
-
- # @api private
- def self.serializer_lookup_chain_for(klass, namespace = nil)
- lookups = ActiveModelSerializers.config.serializer_lookup_chain
- Array[*lookups].flat_map do |lookup|
- lookup.call(klass, self, namespace)
- end.compact
- end
-
- # Used to cache serializer name => serializer class
- # when looked up by Serializer.get_serializer_for.
- def self.serializers_cache
- @serializers_cache ||= ThreadSafe::Cache.new
- end
-
- # @api private
- # Find a serializer from a class and caches the lookup.
- # Preferentially returns:
- # 1. class name appended with "Serializer"
- # 2. try again with superclass, if present
- # 3. nil
- def self.get_serializer_for(klass, namespace = nil)
- return nil unless config.serializer_lookup_enabled
-
- cache_key = ActiveSupport::Cache.expand_cache_key(klass, namespace)
- serializers_cache.fetch_or_store(cache_key) do
- # NOTE(beauby): When we drop 1.9.3 support we can lazify the map for perfs.
- lookup_chain = serializer_lookup_chain_for(klass, namespace)
- serializer_class = lookup_chain.map(&:safe_constantize).find { |x| x && x < ActiveModel::Serializer }
-
- if serializer_class
- serializer_class
- elsif klass.superclass
- get_serializer_for(klass.superclass)
- else
- nil # No serializer found
- end
- end
- end
-
- # @api private
- def self.include_directive_from_options(options)
- if options[:include_directive]
- options[:include_directive]
- elsif options[:include]
- JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true)
- else
- ActiveModelSerializers.default_include_directive
- end
- end
-
- # @api private
- def self.serialization_adapter_instance
- @serialization_adapter_instance ||= ActiveModelSerializers::Adapter::Attributes
- end
-
- # Preferred interface is ActiveModelSerializers.config
- # BEGIN DEFAULT CONFIGURATION
- config.collection_serializer = ActiveModel::Serializer::CollectionSerializer
- config.serializer_lookup_enabled = true
-
- # @deprecated Use {#config.collection_serializer=} instead of this. Is
- # compatibility layer for ArraySerializer.
- def config.array_serializer=(collection_serializer)
- self.collection_serializer = collection_serializer
- end
-
- # @deprecated Use {#config.collection_serializer} instead of this. Is
- # compatibility layer for ArraySerializer.
- def config.array_serializer
- collection_serializer
- end
-
- config.default_includes = '*'
- config.adapter = :attributes
- config.key_transform = nil
- config.jsonapi_pagination_links_enabled = true
- config.jsonapi_resource_type = :plural
- config.jsonapi_namespace_separator = '-'.freeze
- config.jsonapi_version = '1.0'
- config.jsonapi_toplevel_meta = {}
- # Make JSON API top-level jsonapi member opt-in
- # ref: http://jsonapi.org/format/#document-top-level
- config.jsonapi_include_toplevel_object = false
- config.include_data_default = true
-
- # For configuring how serializers are found.
- # This should be an array of procs.
- #
- # The priority of the output is that the first item
- # in the evaluated result array will take precedence
- # over other possible serializer paths.
- #
- # i.e.: First match wins.
- #
- # @example output
- # => [
- # "CustomNamespace::ResourceSerializer",
- # "ParentSerializer::ResourceSerializer",
- # "ResourceNamespace::ResourceSerializer" ,
- # "ResourceSerializer"]
- #
- # If CustomNamespace::ResourceSerializer exists, it will be used
- # for serialization
- config.serializer_lookup_chain = ActiveModelSerializers::LookupChain::DEFAULT.dup
-
- config.schema_path = 'test/support/schemas'
- # END DEFAULT CONFIGURATION
-
- with_options instance_writer: false, instance_reader: false do |serializer|
- serializer.class_attribute :_attributes_data # @api private
- self._attributes_data ||= {}
- end
- with_options instance_writer: false, instance_reader: true do |serializer|
- serializer.class_attribute :_reflections
- self._reflections ||= {}
- serializer.class_attribute :_links # @api private
- self._links ||= {}
- serializer.class_attribute :_meta # @api private
- serializer.class_attribute :_type # @api private
- end
-
- def self.inherited(base)
- super
- base._attributes_data = _attributes_data.dup
- base._reflections = _reflections.dup
- base._links = _links.dup
- end
-
- # @return [Array] Key names of declared attributes
- # @see Serializer::attribute
- def self._attributes
- _attributes_data.keys
- end
-
- # BEGIN SERIALIZER MACROS
-
- # @example
- # class AdminAuthorSerializer < ActiveModel::Serializer
- # attributes :id, :name, :recent_edits
- def self.attributes(*attrs)
- attrs = attrs.first if attrs.first.class == Array
-
- attrs.each do |attr|
- attribute(attr)
- end
- end
-
- # @example
- # class AdminAuthorSerializer < ActiveModel::Serializer
- # attributes :id, :recent_edits
- # attribute :name, key: :title
- #
- # attribute :full_name do
- # "#{object.first_name} #{object.last_name}"
- # end
- #
- # def recent_edits
- # object.edits.last(5)
- # end
- def self.attribute(attr, options = {}, &block)
- key = options.fetch(:key, attr)
- _attributes_data[key] = Attribute.new(attr, options, block)
- end
-
- # @param [Symbol] name of the association
- # @param [Hash any>] options for the reflection
- # @return [void]
- #
- # @example
- # has_many :comments, serializer: CommentSummarySerializer
- #
- def self.has_many(name, options = {}, &block) # rubocop:disable Style/PredicateName
- associate(HasManyReflection.new(name, options, block))
- end
-
- # @param [Symbol] name of the association
- # @param [Hash any>] options for the reflection
- # @return [void]
- #
- # @example
- # belongs_to :author, serializer: AuthorSerializer
- #
- def self.belongs_to(name, options = {}, &block)
- associate(BelongsToReflection.new(name, options, block))
- end
-
- # @param [Symbol] name of the association
- # @param [Hash any>] options for the reflection
- # @return [void]
- #
- # @example
- # has_one :author, serializer: AuthorSerializer
- #
- def self.has_one(name, options = {}, &block) # rubocop:disable Style/PredicateName
- associate(HasOneReflection.new(name, options, block))
- end
-
- # Add reflection and define {name} accessor.
- # @param [ActiveModel::Serializer::Reflection] reflection
- # @return [void]
- #
- # @api private
- def self.associate(reflection)
- key = reflection.options[:key] || reflection.name
- self._reflections[key] = reflection
- end
- private_class_method :associate
-
- # Define a link on a serializer.
- # @example
- # link(:self) { resource_url(object) }
- # @example
- # link(:self) { "http://example.com/resource/#{object.id}" }
- # @example
- # link :resource, "http://example.com/resource"
- #
- def self.link(name, value = nil, &block)
- _links[name] = block || value
- end
-
- # Set the JSON API meta attribute of a serializer.
- # @example
- # class AdminAuthorSerializer < ActiveModel::Serializer
- # meta { stuff: 'value' }
- # @example
- # meta do
- # { comment_count: object.comments.count }
- # end
- def self.meta(value = nil, &block)
- self._meta = block || value
- end
-
- # Set the JSON API type of a serializer.
- # @example
- # class AdminAuthorSerializer < ActiveModel::Serializer
- # type 'authors'
- def self.type(type)
- self._type = type && type.to_s
- end
-
- # END SERIALIZER MACROS
-
- attr_accessor :object, :root, :scope
-
- # `scope_name` is set as :current_user by default in the controller.
- # If the instance does not have a method named `scope_name`, it
- # defines the method so that it calls the +scope+.
- def initialize(object, options = {})
- self.object = object
- self.instance_options = options
- self.root = instance_options[:root]
- self.scope = instance_options[:scope]
-
- return if !(scope_name = instance_options[:scope_name]) || respond_to?(scope_name)
-
- define_singleton_method scope_name, -> { scope }
- end
-
- def success?
- true
- end
-
- # Return the +attributes+ of +object+ as presented
- # by the serializer.
- def attributes(requested_attrs = nil, reload = false)
- @attributes = nil if reload
- @attributes ||= self.class._attributes_data.each_with_object({}) do |(key, attr), hash|
- next if attr.excluded?(self)
- next unless requested_attrs.nil? || requested_attrs.include?(key)
- hash[key] = attr.value(self)
- end
- end
-
- # @param [JSONAPI::IncludeDirective] include_directive (defaults to the
- # +default_include_directive+ config value when not provided)
- # @return [Enumerator]
- def associations(include_directive = ActiveModelSerializers.default_include_directive, include_slice = nil)
- include_slice ||= include_directive
- return Enumerator.new unless object
-
- Enumerator.new do |y|
- self.class._reflections.each do |key, reflection|
- next if reflection.excluded?(self)
- next unless include_directive.key?(key)
-
- association = reflection.build_association(self, instance_options, include_slice)
- y.yield association
- end
- end
- end
-
- # @return [Hash] containing the attributes and first level
- # associations, similar to how ActiveModel::Serializers::JSON is used
- # in ActiveRecord::Base.
- 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)
- resource = attributes_hash(adapter_options, options, adapter_instance)
- relationships = associations_hash(adapter_options, options, adapter_instance)
- resource.merge(relationships)
- end
- alias to_hash serializable_hash
- alias to_h serializable_hash
-
- # @see #serializable_hash
- def as_json(adapter_opts = nil)
- serializable_hash(adapter_opts)
- end
-
- # Used by adapter as resource root.
- def json_key
- root || _type || object.class.model_name.to_s.underscore
- end
-
- def read_attribute_for_serialization(attr)
- if respond_to?(attr)
- send(attr)
- else
- object.read_attribute_for_serialization(attr)
- end
- end
-
- # @api private
- def attributes_hash(_adapter_options, options, adapter_instance)
- if self.class.cache_enabled?
- fetch_attributes(options[:fields], options[:cached_attributes] || {}, adapter_instance)
- elsif self.class.fragment_cache_enabled?
- fetch_attributes_fragment(adapter_instance, options[:cached_attributes] || {})
- else
- attributes(options[:fields], true)
- end
- end
-
- # @api private
- def associations_hash(adapter_options, options, adapter_instance)
- include_directive = options.fetch(:include_directive)
- include_slice = options[:include_slice]
- associations(include_directive, include_slice).each_with_object({}) do |association, relationships|
- adapter_opts = adapter_options.merge(include_directive: include_directive[association.key], adapter_instance: adapter_instance)
- relationships[association.key] = association.serializable_hash(adapter_opts, adapter_instance)
- end
- end
-
- protected
-
- attr_accessor :instance_options
- end
-end
diff --git a/lib/active_model/serializer/adapter.rb b/lib/active_model/serializer/adapter.rb
deleted file mode 100644
index 6b5f30ca..00000000
--- a/lib/active_model/serializer/adapter.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-require 'active_model_serializers/adapter'
-require 'active_model_serializers/deprecate'
-
-module ActiveModel
- class Serializer
- # @deprecated Use ActiveModelSerializers::Adapter instead
- module Adapter
- class << self
- extend ActiveModelSerializers::Deprecate
-
- DEPRECATED_METHODS = [:create, :adapter_class, :adapter_map, :adapters, :register, :lookup].freeze
- DEPRECATED_METHODS.each do |method|
- delegate_and_deprecate method, ActiveModelSerializers::Adapter
- end
- end
- end
- end
-end
-
-require 'active_model/serializer/adapter/base'
-require 'active_model/serializer/adapter/null'
-require 'active_model/serializer/adapter/attributes'
-require 'active_model/serializer/adapter/json'
-require 'active_model/serializer/adapter/json_api'
diff --git a/lib/active_model/serializer/adapter/attributes.rb b/lib/active_model/serializer/adapter/attributes.rb
deleted file mode 100644
index e04e5fd8..00000000
--- a/lib/active_model/serializer/adapter/attributes.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module ActiveModel
- class Serializer
- module Adapter
- class Attributes < DelegateClass(ActiveModelSerializers::Adapter::Attributes)
- def initialize(serializer, options = {})
- super(ActiveModelSerializers::Adapter::Attributes.new(serializer, options))
- end
- class << self
- extend ActiveModelSerializers::Deprecate
- deprecate :new, 'ActiveModelSerializers::Adapter::Json.'
- end
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/adapter/base.rb b/lib/active_model/serializer/adapter/base.rb
deleted file mode 100644
index 013a9705..00000000
--- a/lib/active_model/serializer/adapter/base.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-module ActiveModel
- class Serializer
- module Adapter
- class Base < DelegateClass(ActiveModelSerializers::Adapter::Base)
- class << self
- extend ActiveModelSerializers::Deprecate
- deprecate :inherited, 'ActiveModelSerializers::Adapter::Base.'
- end
-
- # :nocov:
- def initialize(serializer, options = {})
- super(ActiveModelSerializers::Adapter::Base.new(serializer, options))
- end
- # :nocov:
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/adapter/json.rb b/lib/active_model/serializer/adapter/json.rb
deleted file mode 100644
index 1998a4c6..00000000
--- a/lib/active_model/serializer/adapter/json.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module ActiveModel
- class Serializer
- module Adapter
- class Json < DelegateClass(ActiveModelSerializers::Adapter::Json)
- def initialize(serializer, options = {})
- super(ActiveModelSerializers::Adapter::Json.new(serializer, options))
- end
- class << self
- extend ActiveModelSerializers::Deprecate
- deprecate :new, 'ActiveModelSerializers::Adapter::Json.new'
- end
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/adapter/json_api.rb b/lib/active_model/serializer/adapter/json_api.rb
deleted file mode 100644
index 13777cdc..00000000
--- a/lib/active_model/serializer/adapter/json_api.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module ActiveModel
- class Serializer
- module Adapter
- class JsonApi < DelegateClass(ActiveModelSerializers::Adapter::JsonApi)
- def initialize(serializer, options = {})
- super(ActiveModelSerializers::Adapter::JsonApi.new(serializer, options))
- end
- class << self
- extend ActiveModelSerializers::Deprecate
- deprecate :new, 'ActiveModelSerializers::Adapter::JsonApi.new'
- end
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/adapter/null.rb b/lib/active_model/serializer/adapter/null.rb
deleted file mode 100644
index 906953d1..00000000
--- a/lib/active_model/serializer/adapter/null.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module ActiveModel
- class Serializer
- module Adapter
- class Null < DelegateClass(ActiveModelSerializers::Adapter::Null)
- def initialize(serializer, options = {})
- super(ActiveModelSerializers::Adapter::Null.new(serializer, options))
- end
- class << self
- extend ActiveModelSerializers::Deprecate
- deprecate :new, 'ActiveModelSerializers::Adapter::Null.new'
- end
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/array_serializer.rb b/lib/active_model/serializer/array_serializer.rb
deleted file mode 100644
index 2e768deb..00000000
--- a/lib/active_model/serializer/array_serializer.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require 'active_model/serializer/collection_serializer'
-
-module ActiveModel
- class Serializer
- class ArraySerializer < CollectionSerializer
- class << self
- extend ActiveModelSerializers::Deprecate
- deprecate :new, 'ActiveModel::Serializer::CollectionSerializer.'
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/association.rb b/lib/active_model/serializer/association.rb
deleted file mode 100644
index 7ce82316..00000000
--- a/lib/active_model/serializer/association.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-require 'active_model/serializer/lazy_association'
-
-module ActiveModel
- class Serializer
- # This class holds all information about serializer's association.
- #
- # @api private
- Association = Struct.new(:reflection, :association_options) do
- attr_reader :lazy_association
- delegate :object, :include_data?, :virtual_value, :collection?, to: :lazy_association
-
- def initialize(*)
- super
- @lazy_association = LazyAssociation.new(reflection, association_options)
- end
-
- # @return [Symbol]
- delegate :name, to: :reflection
-
- # @return [Symbol]
- def key
- reflection_options.fetch(:key, name)
- end
-
- # @return [True,False]
- def key?
- reflection_options.key?(:key)
- end
-
- # @return [Hash]
- def links
- reflection_options.fetch(:links) || {}
- end
-
- # @return [Hash, nil]
- # This gets mutated, so cannot use the cached reflection_options
- def meta
- reflection.options[:meta]
- end
-
- def belongs_to?
- reflection.foreign_key_on == :self
- end
-
- def polymorphic?
- true == reflection_options[:polymorphic]
- end
-
- # @api private
- def serializable_hash(adapter_options, adapter_instance)
- association_serializer = lazy_association.serializer
- return virtual_value if virtual_value
- association_object = association_serializer && association_serializer.object
- return unless association_object
-
- serialization = association_serializer.serializable_hash(adapter_options, {}, adapter_instance)
-
- if polymorphic? && serialization
- polymorphic_type = association_object.class.name.underscore
- serialization = { type: polymorphic_type, polymorphic_type.to_sym => serialization }
- end
-
- serialization
- end
-
- private
-
- delegate :reflection_options, to: :lazy_association
- end
- end
-end
diff --git a/lib/active_model/serializer/attribute.rb b/lib/active_model/serializer/attribute.rb
deleted file mode 100644
index d3e006fa..00000000
--- a/lib/active_model/serializer/attribute.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require 'active_model/serializer/field'
-
-module ActiveModel
- class Serializer
- # Holds all the meta-data about an attribute as it was specified in the
- # ActiveModel::Serializer class.
- #
- # @example
- # class PostSerializer < ActiveModel::Serializer
- # attribute :content
- # attribute :name, key: :title
- # attribute :email, key: :author_email, if: :user_logged_in?
- # attribute :preview do
- # truncate(object.content)
- # end
- #
- # def user_logged_in?
- # current_user.logged_in?
- # end
- # end
- #
- class Attribute < Field
- end
- end
-end
diff --git a/lib/active_model/serializer/belongs_to_reflection.rb b/lib/active_model/serializer/belongs_to_reflection.rb
deleted file mode 100644
index 04bbc6fc..00000000
--- a/lib/active_model/serializer/belongs_to_reflection.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-module ActiveModel
- class Serializer
- # @api private
- class BelongsToReflection < Reflection
- # @api private
- def foreign_key_on
- :self
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/collection_serializer.rb b/lib/active_model/serializer/collection_serializer.rb
deleted file mode 100644
index 44b806a1..00000000
--- a/lib/active_model/serializer/collection_serializer.rb
+++ /dev/null
@@ -1,87 +0,0 @@
-module ActiveModel
- class Serializer
- class CollectionSerializer
- include Enumerable
- delegate :each, to: :@serializers
-
- attr_reader :object, :root
-
- def initialize(resources, options = {})
- @object = resources
- @options = options
- @root = options[:root]
- @serializers = serializers_from_resources
- end
-
- def success?
- true
- end
-
- # @api private
- def serializable_hash(adapter_options, options, adapter_instance)
- include_directive = ActiveModel::Serializer.include_directive_from_options(adapter_options)
- adapter_options[:cached_attributes] ||= ActiveModel::Serializer.cache_read_multi(self, adapter_instance, include_directive)
- adapter_opts = adapter_options.merge(include_directive: include_directive)
- serializers.map do |serializer|
- serializer.serializable_hash(adapter_opts, options, adapter_instance)
- end
- end
-
- # TODO: unify naming of root, json_key, and _type. Right now, a serializer's
- # json_key comes from the root option or the object's model name, by default.
- # But, if a dev defines a custom `json_key` method with an explicit value,
- # we have no simple way to know that it is safe to call that instance method.
- # (which is really a class property at this point, anyhow).
- # rubocop:disable Metrics/CyclomaticComplexity
- # Disabling cop since it's good to highlight the complexity of this method by
- # including all the logic right here.
- def json_key
- return root if root
- # 1. get from options[:serializer] for empty resource collection
- key = object.empty? &&
- (explicit_serializer_class = options[:serializer]) &&
- explicit_serializer_class._type
- # 2. get from first serializer instance in collection
- key ||= (serializer = serializers.first) && serializer.json_key
- # 3. get from collection name, if a named collection
- key ||= object.respond_to?(:name) ? object.name && object.name.underscore : nil
- # 4. key may be nil for empty collection and no serializer option
- key && key.pluralize
- end
- # rubocop:enable Metrics/CyclomaticComplexity
-
- def paginated?
- ActiveModelSerializers.config.jsonapi_pagination_links_enabled &&
- object.respond_to?(:current_page) &&
- object.respond_to?(:total_pages) &&
- object.respond_to?(:size)
- end
-
- protected
-
- attr_reader :serializers, :options
-
- private
-
- def serializers_from_resources
- serializer_context_class = options.fetch(:serializer_context_class, ActiveModel::Serializer)
- object.map do |resource|
- serializer_from_resource(resource, serializer_context_class, options)
- end
- end
-
- def serializer_from_resource(resource, serializer_context_class, options)
- serializer_class = options.fetch(:serializer) do
- serializer_context_class.serializer_for(resource, namespace: options[:namespace])
- end
-
- if serializer_class.nil?
- ActiveModelSerializers.logger.debug "No serializer found for resource: #{resource.inspect}"
- throw :no_serializer
- else
- serializer_class.new(resource, options.except(:serializer))
- end
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/concerns/caching.rb b/lib/active_model/serializer/concerns/caching.rb
deleted file mode 100644
index 2a030b68..00000000
--- a/lib/active_model/serializer/concerns/caching.rb
+++ /dev/null
@@ -1,300 +0,0 @@
-module ActiveModel
- class Serializer
- UndefinedCacheKey = Class.new(StandardError)
- module Caching
- extend ActiveSupport::Concern
-
- included do
- with_options instance_writer: false, instance_reader: false do |serializer|
- serializer.class_attribute :_cache # @api private : the cache store
- serializer.class_attribute :_cache_key # @api private : when present, is first item in cache_key. Ignored if the serializable object defines #cache_key.
- serializer.class_attribute :_cache_only # @api private : when fragment caching, whitelists fetch_attributes. Cannot combine with except
- serializer.class_attribute :_cache_except # @api private : when fragment caching, blacklists fetch_attributes. Cannot combine with only
- serializer.class_attribute :_cache_options # @api private : used by CachedSerializer, passed to _cache.fetch
- # _cache_options include:
- # expires_in
- # compress
- # force
- # race_condition_ttl
- # Passed to ::_cache as
- # serializer.cache_store.fetch(cache_key, @klass._cache_options)
- # Passed as second argument to serializer.cache_store.fetch(cache_key, serializer_class._cache_options)
- serializer.class_attribute :_cache_digest_file_path # @api private : Derived at inheritance
- end
- end
-
- # Matches
- # "c:/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb:1:in `'"
- # AND
- # "/c/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb:1:in `'"
- # AS
- # c/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb
- CALLER_FILE = /
- \A # start of string
- .+ # file path (one or more characters)
- (?= # stop previous match when
- :\d+ # a colon is followed by one or more digits
- :in # followed by a colon followed by in
- )
- /x
-
- module ClassMethods
- def inherited(base)
- caller_line = caller[1]
- base._cache_digest_file_path = caller_line
- super
- end
-
- def _cache_digest
- return @_cache_digest if defined?(@_cache_digest)
- @_cache_digest = digest_caller_file(_cache_digest_file_path)
- end
-
- # Hashes contents of file for +_cache_digest+
- def digest_caller_file(caller_line)
- serializer_file_path = caller_line[CALLER_FILE]
- serializer_file_contents = IO.read(serializer_file_path)
- Digest::MD5.hexdigest(serializer_file_contents)
- rescue TypeError, Errno::ENOENT
- warn <<-EOF.strip_heredoc
- Cannot digest non-existent file: '#{caller_line}'.
- Please set `::_cache_digest` of the serializer
- if you'd like to cache it.
- EOF
- ''.freeze
- end
-
- def _skip_digest?
- _cache_options && _cache_options[:skip_digest]
- end
-
- # @api private
- # maps attribute value to explicit key name
- # @see Serializer::attribute
- # @see Serializer::fragmented_attributes
- def _attributes_keys
- _attributes_data
- .each_with_object({}) do |(key, attr), hash|
- next if key == attr.name
- hash[attr.name] = { key: key }
- end
- end
-
- def fragmented_attributes
- cached = _cache_only ? _cache_only : _attributes - _cache_except
- cached = cached.map! { |field| _attributes_keys.fetch(field, field) }
- non_cached = _attributes - cached
- non_cached = non_cached.map! { |field| _attributes_keys.fetch(field, field) }
- {
- cached: cached,
- non_cached: non_cached
- }
- end
-
- # Enables a serializer to be automatically cached
- #
- # Sets +::_cache+ object to ActionController::Base.cache_store
- # when Rails.configuration.action_controller.perform_caching
- #
- # @param options [Hash] with valid keys:
- # cache_store : @see ::_cache
- # key : @see ::_cache_key
- # only : @see ::_cache_only
- # except : @see ::_cache_except
- # skip_digest : does not include digest in cache_key
- # all else : @see ::_cache_options
- #
- # @example
- # class PostSerializer < ActiveModel::Serializer
- # cache key: 'post', expires_in: 3.hours
- # attributes :title, :body
- #
- # has_many :comments
- # end
- #
- # @todo require less code comments. See
- # https://github.com/rails-api/active_model_serializers/pull/1249#issuecomment-146567837
- def cache(options = {})
- self._cache =
- options.delete(:cache_store) ||
- ActiveModelSerializers.config.cache_store ||
- ActiveSupport::Cache.lookup_store(:null_store)
- self._cache_key = options.delete(:key)
- self._cache_only = options.delete(:only)
- self._cache_except = options.delete(:except)
- self._cache_options = options.empty? ? nil : options
- end
-
- # Value is from ActiveModelSerializers.config.perform_caching. Is used to
- # globally enable or disable all serializer caching, just like
- # Rails.configuration.action_controller.perform_caching, which is its
- # default value in a Rails application.
- # @return [true, false]
- # Memoizes value of config first time it is called with a non-nil value.
- # rubocop:disable Style/ClassVars
- def perform_caching
- return @@perform_caching if defined?(@@perform_caching) && !@@perform_caching.nil?
- @@perform_caching = ActiveModelSerializers.config.perform_caching
- end
- alias perform_caching? perform_caching
- # rubocop:enable Style/ClassVars
-
- # The canonical method for getting the cache store for the serializer.
- #
- # @return [nil] when _cache is not set (i.e. when `cache` has not been called)
- # @return [._cache] when _cache is not the NullStore
- # @return [ActiveModelSerializers.config.cache_store] when _cache is the NullStore.
- # This is so we can use `cache` being called to mean the serializer should be cached
- # even if ActiveModelSerializers.config.cache_store has not yet been set.
- # That means that when _cache is the NullStore and ActiveModelSerializers.config.cache_store
- # is configured, `cache_store` becomes `ActiveModelSerializers.config.cache_store`.
- # @return [nil] when _cache is the NullStore and ActiveModelSerializers.config.cache_store is nil.
- def cache_store
- return nil if _cache.nil?
- return _cache if _cache.class != ActiveSupport::Cache::NullStore
- if ActiveModelSerializers.config.cache_store
- self._cache = ActiveModelSerializers.config.cache_store
- else
- nil
- end
- end
-
- def cache_enabled?
- perform_caching? && cache_store && !_cache_only && !_cache_except
- end
-
- def fragment_cache_enabled?
- perform_caching? && cache_store &&
- (_cache_only && !_cache_except || !_cache_only && _cache_except)
- end
-
- # Read cache from cache_store
- # @return [Hash]
- # Used in CollectionSerializer to set :cached_attributes
- def cache_read_multi(collection_serializer, adapter_instance, include_directive)
- return {} if ActiveModelSerializers.config.cache_store.blank?
-
- keys = object_cache_keys(collection_serializer, adapter_instance, include_directive)
-
- return {} if keys.blank?
-
- ActiveModelSerializers.config.cache_store.read_multi(*keys)
- end
-
- # Find all cache_key for the collection_serializer
- # @param serializers [ActiveModel::Serializer::CollectionSerializer]
- # @param adapter_instance [ActiveModelSerializers::Adapter::Base]
- # @param include_directive [JSONAPI::IncludeDirective]
- # @return [Array] all cache_key of collection_serializer
- def object_cache_keys(collection_serializer, adapter_instance, include_directive)
- cache_keys = []
-
- collection_serializer.each do |serializer|
- cache_keys << object_cache_key(serializer, adapter_instance)
-
- serializer.associations(include_directive).each do |association|
- # TODO(BF): Process relationship without evaluating lazy_association
- association_serializer = association.lazy_association.serializer
- if association_serializer.respond_to?(:each)
- association_serializer.each do |sub_serializer|
- cache_keys << object_cache_key(sub_serializer, adapter_instance)
- end
- else
- cache_keys << object_cache_key(association_serializer, adapter_instance)
- end
- end
- end
-
- cache_keys.compact.uniq
- end
-
- # @return [String, nil] the cache_key of the serializer or nil
- def object_cache_key(serializer, adapter_instance)
- return unless serializer.present? && serializer.object.present?
-
- (serializer.class.cache_enabled? || serializer.class.fragment_cache_enabled?) ? serializer.cache_key(adapter_instance) : nil
- end
- end
-
- ### INSTANCE METHODS
- def fetch_attributes(fields, cached_attributes, adapter_instance)
- key = cache_key(adapter_instance)
- cached_attributes.fetch(key) do
- fetch(adapter_instance, serializer_class._cache_options, key) do
- attributes(fields, true)
- end
- end
- end
-
- def fetch(adapter_instance, cache_options = serializer_class._cache_options, key = nil)
- if serializer_class.cache_store
- key ||= cache_key(adapter_instance)
- serializer_class.cache_store.fetch(key, cache_options) do
- yield
- end
- else
- yield
- end
- end
-
- # 1. Determine cached fields from serializer class options
- # 2. Get non_cached_fields and fetch cache_fields
- # 3. Merge the two hashes using adapter_instance#fragment_cache
- def fetch_attributes_fragment(adapter_instance, cached_attributes = {})
- serializer_class._cache_options ||= {}
- serializer_class._cache_options[:key] = serializer_class._cache_key if serializer_class._cache_key
- fields = serializer_class.fragmented_attributes
-
- non_cached_fields = fields[:non_cached].dup
- non_cached_hash = attributes(non_cached_fields, true)
- include_directive = JSONAPI::IncludeDirective.new(non_cached_fields - non_cached_hash.keys)
- non_cached_hash.merge! associations_hash({}, { include_directive: include_directive }, adapter_instance)
-
- cached_fields = fields[:cached].dup
- key = cache_key(adapter_instance)
- cached_hash =
- cached_attributes.fetch(key) do
- fetch(adapter_instance, serializer_class._cache_options, key) do
- hash = attributes(cached_fields, true)
- include_directive = JSONAPI::IncludeDirective.new(cached_fields - hash.keys)
- hash.merge! associations_hash({}, { include_directive: include_directive }, adapter_instance)
- end
- end
- # Merge both results
- adapter_instance.fragment_cache(cached_hash, non_cached_hash)
- end
-
- def cache_key(adapter_instance)
- return @cache_key if defined?(@cache_key)
-
- parts = []
- parts << object_cache_key
- parts << adapter_instance.cache_key
- parts << serializer_class._cache_digest unless serializer_class._skip_digest?
- @cache_key = expand_cache_key(parts)
- end
-
- def expand_cache_key(parts)
- ActiveSupport::Cache.expand_cache_key(parts)
- end
-
- # Use object's cache_key if available, else derive a key from the object
- # Pass the `key` option to the `cache` declaration or override this method to customize the cache key
- def object_cache_key
- if object.respond_to?(:cache_key)
- object.cache_key
- elsif (serializer_cache_key = (serializer_class._cache_key || serializer_class._cache_options[:key]))
- object_time_safe = object.updated_at
- object_time_safe = object_time_safe.strftime('%Y%m%d%H%M%S%9N') if object_time_safe.respond_to?(:strftime)
- "#{serializer_cache_key}/#{object.id}-#{object_time_safe}"
- else
- fail UndefinedCacheKey, "#{object.class} must define #cache_key, or the 'key:' option must be passed into '#{serializer_class}.cache'"
- end
- end
-
- def serializer_class
- @serializer_class ||= self.class
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/error_serializer.rb b/lib/active_model/serializer/error_serializer.rb
deleted file mode 100644
index d0e70809..00000000
--- a/lib/active_model/serializer/error_serializer.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-module ActiveModel
- class Serializer
- class ErrorSerializer < ActiveModel::Serializer
- # @return [Hash>]
- def as_json
- object.errors.messages
- end
-
- def success?
- false
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/errors_serializer.rb b/lib/active_model/serializer/errors_serializer.rb
deleted file mode 100644
index 1fd924d5..00000000
--- a/lib/active_model/serializer/errors_serializer.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-require 'active_model/serializer/error_serializer'
-
-module ActiveModel
- class Serializer
- class ErrorsSerializer
- include Enumerable
- delegate :each, to: :@serializers
- attr_reader :object, :root
-
- def initialize(resources, options = {})
- @root = options[:root]
- @object = resources
- @serializers = resources.map do |resource|
- serializer_class = options.fetch(:serializer) { ActiveModel::Serializer::ErrorSerializer }
- serializer_class.new(resource, options.except(:serializer))
- end
- end
-
- def success?
- false
- end
-
- def json_key
- nil
- end
-
- protected
-
- attr_reader :serializers
- end
- end
-end
diff --git a/lib/active_model/serializer/field.rb b/lib/active_model/serializer/field.rb
deleted file mode 100644
index 6299b099..00000000
--- a/lib/active_model/serializer/field.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-module ActiveModel
- class Serializer
- # Holds all the meta-data about a field (i.e. attribute or association) as it was
- # specified in the ActiveModel::Serializer class.
- # Notice that the field block is evaluated in the context of the serializer.
- Field = Struct.new(:name, :options, :block) do
- def initialize(*)
- super
-
- validate_condition!
- end
-
- # Compute the actual value of a field for a given serializer instance.
- # @param [Serializer] The serializer instance for which the value is computed.
- # @return [Object] value
- #
- # @api private
- #
- def value(serializer)
- if block
- serializer.instance_eval(&block)
- else
- serializer.read_attribute_for_serialization(name)
- end
- end
-
- # Decide whether the field should be serialized by the given serializer instance.
- # @param [Serializer] The serializer instance
- # @return [Bool]
- #
- # @api private
- #
- def excluded?(serializer)
- case condition_type
- when :if
- !evaluate_condition(serializer)
- when :unless
- evaluate_condition(serializer)
- else
- false
- end
- end
-
- private
-
- def validate_condition!
- return if condition_type == :none
-
- case condition
- when Symbol, String, Proc
- # noop
- else
- fail TypeError, "#{condition_type.inspect} should be a Symbol, String or Proc"
- end
- end
-
- def evaluate_condition(serializer)
- case condition
- when Symbol
- serializer.public_send(condition)
- when String
- serializer.instance_eval(condition)
- when Proc
- if condition.arity.zero?
- serializer.instance_exec(&condition)
- else
- serializer.instance_exec(serializer, &condition)
- end
- else
- nil
- end
- end
-
- def condition_type
- @condition_type ||=
- if options.key?(:if)
- :if
- elsif options.key?(:unless)
- :unless
- else
- :none
- end
- end
-
- def condition
- options[condition_type]
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/fieldset.rb b/lib/active_model/serializer/fieldset.rb
deleted file mode 100644
index efa3187c..00000000
--- a/lib/active_model/serializer/fieldset.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-module ActiveModel
- class Serializer
- class Fieldset
- def initialize(fields)
- @raw_fields = fields || {}
- end
-
- def fields
- @fields ||= parsed_fields
- end
-
- def fields_for(type)
- fields[type.singularize.to_sym] || fields[type.pluralize.to_sym]
- end
-
- protected
-
- attr_reader :raw_fields
-
- private
-
- def parsed_fields
- if raw_fields.is_a?(Hash)
- raw_fields.each_with_object({}) { |(k, v), h| h[k.to_sym] = v.map(&:to_sym) }
- else
- {}
- end
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/has_many_reflection.rb b/lib/active_model/serializer/has_many_reflection.rb
deleted file mode 100644
index 99f6f63c..00000000
--- a/lib/active_model/serializer/has_many_reflection.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module ActiveModel
- class Serializer
- # @api private
- class HasManyReflection < Reflection
- def collection?
- true
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/has_one_reflection.rb b/lib/active_model/serializer/has_one_reflection.rb
deleted file mode 100644
index a385009b..00000000
--- a/lib/active_model/serializer/has_one_reflection.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module ActiveModel
- class Serializer
- # @api private
- class HasOneReflection < Reflection
- end
- end
-end
diff --git a/lib/active_model/serializer/lazy_association.rb b/lib/active_model/serializer/lazy_association.rb
deleted file mode 100644
index 8c4dad61..00000000
--- a/lib/active_model/serializer/lazy_association.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-module ActiveModel
- class Serializer
- # @api private
- LazyAssociation = Struct.new(:reflection, :association_options) do
- REFLECTION_OPTIONS = %i(key links polymorphic meta serializer virtual_value namespace).freeze
-
- delegate :collection?, to: :reflection
-
- def reflection_options
- @reflection_options ||= reflection.options.dup.reject { |k, _| !REFLECTION_OPTIONS.include?(k) }
- end
-
- def object
- @object ||= reflection.value(
- association_options.fetch(:parent_serializer),
- association_options.fetch(:include_slice)
- )
- end
- alias_method :eval_reflection_block, :object
-
- def include_data?
- eval_reflection_block if reflection.block
- reflection.include_data?(
- association_options.fetch(:include_slice)
- )
- end
-
- # @return [ActiveModel::Serializer, nil]
- def serializer
- return @serializer if defined?(@serializer)
- if serializer_class
- serialize_object!(object)
- elsif !object.nil? && !object.instance_of?(Object)
- cached_result[:virtual_value] = object
- end
- @serializer = cached_result[:serializer]
- end
-
- def virtual_value
- cached_result[:virtual_value] || reflection_options[:virtual_value]
- end
-
- def serializer_class
- return @serializer_class if defined?(@serializer_class)
- serializer_for_options = { namespace: namespace }
- serializer_for_options[:serializer] = reflection_options[:serializer] if reflection_options.key?(:serializer)
- @serializer_class = association_options.fetch(:parent_serializer).class.serializer_for(object, serializer_for_options)
- end
-
- private
-
- def cached_result
- @cached_result ||= {}
- end
-
- def serialize_object!(object)
- if collection?
- if (serializer = instantiate_collection_serializer(object)).nil?
- # BUG: per #2027, JSON API resource relationships are only id and type, and hence either
- # *require* a serializer or we need to be a little clever about figuring out the id/type.
- # In either case, returning the raw virtual value will almost always be incorrect.
- #
- # Should be reflection_options[:virtual_value] or adapter needs to figure out what to do
- # with an object that is non-nil and has no defined serializer.
- cached_result[:virtual_value] = object.try(:as_json) || object
- else
- cached_result[:serializer] = serializer
- end
- else
- cached_result[:serializer] = instantiate_serializer(object)
- end
- end
-
- def instantiate_serializer(object)
- serializer_options = association_options.fetch(:parent_serializer_options).except(:serializer)
- serializer_options[:serializer_context_class] = association_options.fetch(:parent_serializer).class
- serializer = reflection_options.fetch(:serializer, nil)
- serializer_options[:serializer] = serializer if serializer
- serializer_class.new(object, serializer_options)
- end
-
- def instantiate_collection_serializer(object)
- serializer = catch(:no_serializer) do
- instantiate_serializer(object)
- end
- serializer
- end
-
- def namespace
- reflection_options[:namespace] ||
- association_options.fetch(:parent_serializer_options)[:namespace]
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/lint.rb b/lib/active_model/serializer/lint.rb
deleted file mode 100644
index c40cebeb..00000000
--- a/lib/active_model/serializer/lint.rb
+++ /dev/null
@@ -1,150 +0,0 @@
-module ActiveModel
- class Serializer
- module Lint
- # == Active \Model \Serializer \Lint \Tests
- #
- # You can test whether an object is compliant with the Active \Model \Serializers
- # API by including ActiveModel::Serializer::Lint::Tests in your TestCase.
- # It will include tests that tell you whether your object is fully compliant,
- # or if not, which aspects of the API are not implemented.
- #
- # Note an object is not required to implement all APIs in order to work
- # with Active \Model \Serializers. This module only intends to provide guidance in case
- # you want all features out of the box.
- #
- # These tests do not attempt to determine the semantic correctness of the
- # returned values. For instance, you could implement serializable_hash to
- # always return +{}+, and the tests would pass. It is up to you to ensure
- # that the values are semantically meaningful.
- module Tests
- # Passes if the object responds to serializable_hash and if it takes
- # zero or one arguments.
- # Fails otherwise.
- #
- # serializable_hash returns a hash representation of a object's attributes.
- # Typically, it is implemented by including ActiveModel::Serialization.
- def test_serializable_hash
- assert_respond_to resource, :serializable_hash, 'The resource should respond to serializable_hash'
- resource.serializable_hash
- resource.serializable_hash(nil)
- end
-
- # Passes if the object responds to read_attribute_for_serialization
- # and if it requires one argument (the attribute to be read).
- # Fails otherwise.
- #
- # read_attribute_for_serialization gets the attribute value for serialization
- # Typically, it is implemented by including ActiveModel::Serialization.
- def test_read_attribute_for_serialization
- assert_respond_to resource, :read_attribute_for_serialization, 'The resource should respond to read_attribute_for_serialization'
- actual_arity = resource.method(:read_attribute_for_serialization).arity
- # using absolute value since arity is:
- # 1 for def read_attribute_for_serialization(name); end
- # -1 for alias :read_attribute_for_serialization :send
- assert_equal 1, actual_arity.abs, "expected #{actual_arity.inspect}.abs to be 1 or -1"
- end
-
- # Passes if the object responds to as_json and if it takes
- # zero or one arguments.
- # Fails otherwise.
- #
- # as_json returns a hash representation of a serialized object.
- # It may delegate to serializable_hash
- # Typically, it is implemented either by including ActiveModel::Serialization
- # which includes ActiveModel::Serializers::JSON.
- # or by the JSON gem when required.
- def test_as_json
- assert_respond_to resource, :as_json
- resource.as_json
- resource.as_json(nil)
- end
-
- # Passes if the object responds to to_json and if it takes
- # zero or one arguments.
- # Fails otherwise.
- #
- # to_json returns a string representation (JSON) of a serialized object.
- # It may be called on the result of as_json.
- # Typically, it is implemented on all objects when the JSON gem is required.
- def test_to_json
- assert_respond_to resource, :to_json
- resource.to_json
- resource.to_json(nil)
- end
-
- # Passes if the object responds to cache_key
- # Fails otherwise.
- #
- # cache_key returns a (self-expiring) unique key for the object,
- # and is part of the (self-expiring) cache_key, which is used by the
- # adapter. It is not required unless caching is enabled.
- def test_cache_key
- assert_respond_to resource, :cache_key
- actual_arity = resource.method(:cache_key).arity
- assert_includes [-1, 0], actual_arity, "expected #{actual_arity.inspect} to be 0 or -1"
- end
-
- # Passes if the object responds to updated_at and if it takes no
- # arguments.
- # Fails otherwise.
- #
- # updated_at returns a Time object or iso8601 string and
- # is part of the (self-expiring) cache_key, which is used by the adapter.
- # It is not required unless caching is enabled.
- def test_updated_at
- assert_respond_to resource, :updated_at
- actual_arity = resource.method(:updated_at).arity
- assert_equal 0, actual_arity
- end
-
- # Passes if the object responds to id and if it takes no
- # arguments.
- # Fails otherwise.
- #
- # id returns a unique identifier for the object.
- # It is not required unless caching is enabled.
- def test_id
- assert_respond_to resource, :id
- assert_equal 0, resource.method(:id).arity
- end
-
- # Passes if the object's class responds to model_name and if it
- # is in an instance of +ActiveModel::Name+.
- # Fails otherwise.
- #
- # model_name returns an ActiveModel::Name instance.
- # It is used by the serializer to identify the object's type.
- # It is not required unless caching is enabled.
- def test_model_name
- resource_class = resource.class
- assert_respond_to resource_class, :model_name
- assert_instance_of resource_class.model_name, ActiveModel::Name
- end
-
- def test_active_model_errors
- assert_respond_to resource, :errors
- end
-
- def test_active_model_errors_human_attribute_name
- assert_respond_to resource.class, :human_attribute_name
- assert_equal(-2, resource.class.method(:human_attribute_name).arity)
- end
-
- def test_active_model_errors_lookup_ancestors
- assert_respond_to resource.class, :lookup_ancestors
- assert_equal 0, resource.class.method(:lookup_ancestors).arity
- end
-
- private
-
- def resource
- @resource or fail "'@resource' must be set as the linted object"
- end
-
- def assert_instance_of(result, name)
- assert result.instance_of?(name), "#{result} should be an instance of #{name}"
- end
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/null.rb b/lib/active_model/serializer/null.rb
deleted file mode 100644
index 818bbbfa..00000000
--- a/lib/active_model/serializer/null.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-module ActiveModel
- class Serializer
- class Null < Serializer
- def attributes(*)
- {}
- end
-
- def associations(*)
- {}
- end
-
- def serializable_hash(*)
- {}
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/reflection.rb b/lib/active_model/serializer/reflection.rb
deleted file mode 100644
index 2e5cc2a1..00000000
--- a/lib/active_model/serializer/reflection.rb
+++ /dev/null
@@ -1,207 +0,0 @@
-require 'active_model/serializer/field'
-require 'active_model/serializer/association'
-
-module ActiveModel
- class Serializer
- # Holds all the meta-data about an association as it was specified in the
- # ActiveModel::Serializer class.
- #
- # @example
- # class PostSerializer < ActiveModel::Serializer
- # has_one :author, serializer: AuthorSerializer
- # belongs_to :boss, type: :users, foreign_key: :boss_id
- # has_many :comments
- # has_many :comments, key: :last_comments do
- # object.comments.last(1)
- # end
- # has_many :secret_meta_data, if: :is_admin?
- #
- # has_one :blog do |serializer|
- # meta count: object.roles.count
- # serializer.cached_blog
- # end
- #
- # private
- #
- # def cached_blog
- # cache_store.fetch("cached_blog:#{object.updated_at}") do
- # Blog.find(object.blog_id)
- # end
- # end
- #
- # def is_admin?
- # current_user.admin?
- # end
- # end
- #
- # Specifically, the association 'comments' is evaluated two different ways:
- # 1) as 'comments' and named 'comments'.
- # 2) as 'object.comments.last(1)' and named 'last_comments'.
- #
- # PostSerializer._reflections # =>
- # # {
- # # author: HasOneReflection.new(:author, serializer: AuthorSerializer),
- # # comments: HasManyReflection.new(:comments)
- # # last_comments: HasManyReflection.new(:comments, { key: :last_comments }, #)
- # # secret_meta_data: HasManyReflection.new(:secret_meta_data, { if: :is_admin? })
- # # }
- #
- # So you can inspect reflections in your Adapters.
- class Reflection < Field
- attr_reader :foreign_key, :type
-
- def initialize(*)
- super
- options[:links] = {}
- options[:include_data_setting] = Serializer.config.include_data_default
- options[:meta] = nil
- @type = options.fetch(:type) do
- class_name = options.fetch(:class_name, name.to_s.camelize.singularize)
- class_name.underscore.pluralize.to_sym
- end
- @foreign_key = options.fetch(:foreign_key) do
- if collection?
- "#{name.to_s.singularize}_ids".to_sym
- else
- "#{name}_id".to_sym
- end
- end
- end
-
- # @api public
- # @example
- # has_one :blog do
- # include_data false
- # link :self, 'a link'
- # link :related, 'another link'
- # link :self, '//example.com/link_author/relationships/bio'
- # id = object.profile.id
- # link :related do
- # "//example.com/profiles/#{id}" if id != 123
- # end
- # link :related do
- # ids = object.likes.map(&:id).join(',')
- # href "//example.com/likes/#{ids}"
- # meta ids: ids
- # end
- # end
- def link(name, value = nil)
- options[:links][name] = block_given? ? Proc.new : value
- :nil
- end
-
- # @api public
- # @example
- # has_one :blog do
- # include_data false
- # meta(id: object.blog.id)
- # meta liked: object.likes.any?
- # link :self do
- # href object.blog.id.to_s
- # meta(id: object.blog.id)
- # end
- def meta(value = nil)
- options[:meta] = block_given? ? Proc.new : value
- :nil
- end
-
- # @api public
- # @example
- # has_one :blog do
- # include_data false
- # link :self, 'a link'
- # link :related, 'another link'
- # end
- #
- # has_one :blog do
- # include_data false
- # link :self, 'a link'
- # link :related, 'another link'
- # end
- #
- # belongs_to :reviewer do
- # meta name: 'Dan Brown'
- # include_data true
- # end
- #
- # has_many :tags, serializer: TagSerializer do
- # link :self, '//example.com/link_author/relationships/tags'
- # include_data :if_sideloaded
- # end
- def include_data(value = true)
- options[:include_data_setting] = value
- :nil
- end
-
- def collection?
- false
- end
-
- def include_data?(include_slice)
- include_data_setting = options[:include_data_setting]
- case include_data_setting
- when :if_sideloaded then include_slice.key?(name)
- when true then true
- when false then false
- else fail ArgumentError, "Unknown include_data_setting '#{include_data_setting.inspect}'"
- end
- end
-
- # @param serializer [ActiveModel::Serializer]
- # @yield [ActiveModel::Serializer]
- # @return [:nil, associated resource or resource collection]
- def value(serializer, include_slice)
- @object = serializer.object
- @scope = serializer.scope
-
- block_value = instance_exec(serializer, &block) if block
- return unless include_data?(include_slice)
-
- if block && block_value != :nil
- block_value
- else
- serializer.read_attribute_for_serialization(name)
- end
- end
-
- # @api private
- def foreign_key_on
- :related
- end
-
- # Build association. This method is used internally to
- # build serializer's association by its reflection.
- #
- # @param [Serializer] parent_serializer for given association
- # @param [Hash{Symbol => Object}] parent_serializer_options
- #
- # @example
- # # Given the following serializer defined:
- # class PostSerializer < ActiveModel::Serializer
- # has_many :comments, serializer: CommentSummarySerializer
- # end
- #
- # # Then you instantiate your serializer
- # post_serializer = PostSerializer.new(post, foo: 'bar') #
- # # to build association for comments you need to get reflection
- # comments_reflection = PostSerializer._reflections.detect { |r| r.name == :comments }
- # # and #build_association
- # comments_reflection.build_association(post_serializer, foo: 'bar')
- #
- # @api private
- def build_association(parent_serializer, parent_serializer_options, include_slice = {})
- association_options = {
- parent_serializer: parent_serializer,
- parent_serializer_options: parent_serializer_options,
- include_slice: include_slice
- }
- Association.new(self, association_options)
- end
-
- protected
-
- # used in instance exec
- attr_accessor :object, :scope
- end
- end
-end
diff --git a/lib/active_model/serializer/version.rb b/lib/active_model/serializer/version.rb
deleted file mode 100644
index e692240a..00000000
--- a/lib/active_model/serializer/version.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-module ActiveModel
- class Serializer
- VERSION = '0.10.6'.freeze
- end
-end
diff --git a/lib/active_model_serializers.rb b/lib/active_model_serializers.rb
deleted file mode 100644
index 18cdd9f7..00000000
--- a/lib/active_model_serializers.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-require 'active_model'
-require 'active_support'
-require 'active_support/core_ext/object/with_options'
-require 'active_support/core_ext/string/inflections'
-require 'active_support/json'
-module ActiveModelSerializers
- extend ActiveSupport::Autoload
- autoload :Model
- autoload :Callbacks
- autoload :Deserialization
- autoload :SerializableResource
- autoload :Logging
- autoload :Test
- autoload :Adapter
- autoload :JsonPointer
- autoload :Deprecate
- autoload :LookupChain
-
- class << self; attr_accessor :logger; end
- self.logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT))
-
- def self.config
- ActiveModel::Serializer.config
- end
-
- # The file name and line number of the caller of the caller of this method.
- def self.location_of_caller
- caller[1] =~ /(.*?):(\d+).*?$/i
- file = Regexp.last_match(1)
- lineno = Regexp.last_match(2).to_i
-
- [file, lineno]
- end
-
- # Memoized default include directive
- # @return [JSONAPI::IncludeDirective]
- def self.default_include_directive
- @default_include_directive ||= JSONAPI::IncludeDirective.new(config.default_includes, allow_wildcard: true)
- end
-
- def self.silence_warnings
- original_verbose = $VERBOSE
- $VERBOSE = nil
- yield
- ensure
- $VERBOSE = original_verbose
- end
-
- require 'active_model/serializer/version'
- require 'active_model/serializer'
- require 'active_model/serializable_resource'
- require 'active_model_serializers/railtie' if defined?(::Rails)
-end
diff --git a/lib/active_model_serializers/adapter.rb b/lib/active_model_serializers/adapter.rb
deleted file mode 100644
index 98caab44..00000000
--- a/lib/active_model_serializers/adapter.rb
+++ /dev/null
@@ -1,98 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- UnknownAdapterError = Class.new(ArgumentError)
- ADAPTER_MAP = {} # rubocop:disable Style/MutableConstant
- private_constant :ADAPTER_MAP if defined?(private_constant)
-
- class << self # All methods are class functions
- # :nocov:
- def new(*args)
- fail ArgumentError, 'Adapters inherit from Adapter::Base.' \
- "Adapter.new called with args: '#{args.inspect}', from" \
- "'caller[0]'."
- end
- # :nocov:
-
- def configured_adapter
- lookup(ActiveModelSerializers.config.adapter)
- end
-
- def create(resource, options = {})
- override = options.delete(:adapter)
- klass = override ? adapter_class(override) : configured_adapter
- klass.new(resource, options)
- end
-
- # @see ActiveModelSerializers::Adapter.lookup
- def adapter_class(adapter)
- ActiveModelSerializers::Adapter.lookup(adapter)
- end
-
- # @return [Hash]
- def adapter_map
- ADAPTER_MAP
- end
-
- # @return [Array] list of adapter names
- def adapters
- adapter_map.keys.sort
- end
-
- # Adds an adapter 'klass' with 'name' to the 'adapter_map'
- # Names are stringified and underscored
- # @param name [Symbol, String, Class] name of the registered adapter
- # @param klass [Class] adapter class itself, optional if name is the class
- # @example
- # AMS::Adapter.register(:my_adapter, MyAdapter)
- # @note The registered name strips out 'ActiveModelSerializers::Adapter::'
- # so that registering 'ActiveModelSerializers::Adapter::Json' and
- # 'Json' will both register as 'json'.
- def register(name, klass = name)
- name = name.to_s.gsub(/\AActiveModelSerializers::Adapter::/, ''.freeze)
- adapter_map[name.underscore] = klass
- self
- end
-
- def registered_name(adapter_class)
- ADAPTER_MAP.key adapter_class
- end
-
- # @param adapter [String, Symbol, Class] name to fetch adapter by
- # @return [ActiveModelSerializers::Adapter] subclass of Adapter
- # @raise [UnknownAdapterError]
- def lookup(adapter)
- # 1. return if is a class
- return adapter if adapter.is_a?(Class)
- adapter_name = adapter.to_s.underscore
- # 2. return if registered
- adapter_map.fetch(adapter_name) do
- # 3. try to find adapter class from environment
- adapter_class = find_by_name(adapter_name)
- register(adapter_name, adapter_class)
- adapter_class
- end
- rescue NameError, ArgumentError => e
- failure_message =
- "NameError: #{e.message}. Unknown adapter: #{adapter.inspect}. Valid adapters are: #{adapters}"
- raise UnknownAdapterError, failure_message, e.backtrace
- end
-
- # @api private
- def find_by_name(adapter_name)
- adapter_name = adapter_name.to_s.classify.tr('API', 'Api')
- "ActiveModelSerializers::Adapter::#{adapter_name}".safe_constantize ||
- "ActiveModelSerializers::Adapter::#{adapter_name.pluralize}".safe_constantize or # rubocop:disable Style/AndOr
- fail UnknownAdapterError
- end
- private :find_by_name
- end
-
- # Gotta be at the bottom to use the code above it :(
- extend ActiveSupport::Autoload
- autoload :Base
- autoload :Null
- autoload :Attributes
- autoload :Json
- autoload :JsonApi
- end
-end
diff --git a/lib/active_model_serializers/adapter/attributes.rb b/lib/active_model_serializers/adapter/attributes.rb
deleted file mode 100644
index 79ca7b5f..00000000
--- a/lib/active_model_serializers/adapter/attributes.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- class Attributes < Base
- def serializable_hash(options = nil)
- options = serialization_options(options)
- options[:fields] ||= instance_options[:fields]
- serialized_hash = serializer.serializable_hash(instance_options, options, self)
-
- self.class.transform_key_casing!(serialized_hash, instance_options)
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/adapter/base.rb b/lib/active_model_serializers/adapter/base.rb
deleted file mode 100644
index 85158328..00000000
--- a/lib/active_model_serializers/adapter/base.rb
+++ /dev/null
@@ -1,83 +0,0 @@
-require 'case_transform'
-
-module ActiveModelSerializers
- module Adapter
- class Base
- # Automatically register adapters when subclassing
- def self.inherited(subclass)
- ActiveModelSerializers::Adapter.register(subclass)
- end
-
- # Sets the default transform for the adapter.
- #
- # @return [Symbol] the default transform for the adapter
- def self.default_key_transform
- :unaltered
- end
-
- # Determines the transform to use in order of precedence:
- # adapter option, global config, adapter default.
- #
- # @param options [Object]
- # @return [Symbol] the transform to use
- def self.transform(options)
- return options[:key_transform] if options && options[:key_transform]
- ActiveModelSerializers.config.key_transform || default_key_transform
- end
-
- # Transforms the casing of the supplied value.
- #
- # @param value [Object] the value to be transformed
- # @param options [Object] serializable resource options
- # @return [Symbol] the default transform for the adapter
- def self.transform_key_casing!(value, options)
- CaseTransform.send(transform(options), value)
- end
-
- def self.cache_key
- @cache_key ||= ActiveModelSerializers::Adapter.registered_name(self)
- end
-
- def self.fragment_cache(cached_hash, non_cached_hash)
- non_cached_hash.merge cached_hash
- end
-
- attr_reader :serializer, :instance_options
-
- def initialize(serializer, options = {})
- @serializer = serializer
- @instance_options = options
- end
-
- # Subclasses that implement this method must first call
- # options = serialization_options(options)
- def serializable_hash(_options = nil)
- fail NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
- end
-
- def as_json(options = nil)
- serializable_hash(options)
- end
-
- def cache_key
- self.class.cache_key
- end
-
- def fragment_cache(cached_hash, non_cached_hash)
- self.class.fragment_cache(cached_hash, non_cached_hash)
- end
-
- private
-
- # see https://github.com/rails-api/active_model_serializers/pull/965
- # When options is +nil+, sets it to +{}+
- def serialization_options(options)
- options ||= {} # rubocop:disable Lint/UselessAssignment
- end
-
- def root
- serializer.json_key.to_sym if serializer.json_key
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/adapter/json.rb b/lib/active_model_serializers/adapter/json.rb
deleted file mode 100644
index 423cfb9f..00000000
--- a/lib/active_model_serializers/adapter/json.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- class Json < Base
- def serializable_hash(options = nil)
- options = serialization_options(options)
- serialized_hash = { root => Attributes.new(serializer, instance_options).serializable_hash(options) }
- serialized_hash[meta_key] = meta unless meta.blank?
-
- self.class.transform_key_casing!(serialized_hash, instance_options)
- end
-
- def meta
- instance_options.fetch(:meta, nil)
- end
-
- def meta_key
- instance_options.fetch(:meta_key, 'meta'.freeze)
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/adapter/json_api.rb b/lib/active_model_serializers/adapter/json_api.rb
deleted file mode 100644
index b225416b..00000000
--- a/lib/active_model_serializers/adapter/json_api.rb
+++ /dev/null
@@ -1,530 +0,0 @@
-# {http://jsonapi.org/format/ JSON API specification}
-# rubocop:disable Style/AsciiComments
-# TODO: implement!
-# ☐ https://github.com/rails-api/active_model_serializers/issues/1235
-# TODO: use uri_template in link generation?
-# ☐ https://github.com/rails-api/active_model_serializers/pull/1282#discussion_r42528812
-# see gem https://github.com/hannesg/uri_template
-# spec http://tools.ietf.org/html/rfc6570
-# impl https://developer.github.com/v3/#schema https://api.github.com/
-# TODO: validate against a JSON schema document?
-# ☐ https://github.com/rails-api/active_model_serializers/issues/1162
-# ☑ https://github.com/rails-api/active_model_serializers/pull/1270
-# TODO: Routing
-# ☐ https://github.com/rails-api/active_model_serializers/pull/1476
-# TODO: Query Params
-# ☑ `include` https://github.com/rails-api/active_model_serializers/pull/1131
-# ☑ `fields` https://github.com/rails-api/active_model_serializers/pull/700
-# ☑ `page[number]=3&page[size]=1` https://github.com/rails-api/active_model_serializers/pull/1041
-# ☐ `filter`
-# ☐ `sort`
-module ActiveModelSerializers
- module Adapter
- class JsonApi < Base
- extend ActiveSupport::Autoload
- autoload :Jsonapi
- autoload :ResourceIdentifier
- autoload :Relationship
- autoload :Link
- autoload :PaginationLinks
- autoload :Meta
- autoload :Error
- autoload :Deserialization
-
- def self.default_key_transform
- :dash
- end
-
- def self.fragment_cache(cached_hash, non_cached_hash, root = true)
- core_cached = cached_hash.first
- core_non_cached = non_cached_hash.first
- no_root_cache = cached_hash.delete_if { |key, _value| key == core_cached[0] }
- no_root_non_cache = non_cached_hash.delete_if { |key, _value| key == core_non_cached[0] }
- cached_resource = (core_cached[1]) ? core_cached[1].deep_merge(core_non_cached[1]) : core_non_cached[1]
- hash = root ? { root => cached_resource } : cached_resource
-
- hash.deep_merge no_root_non_cache.deep_merge no_root_cache
- end
-
- def initialize(serializer, options = {})
- super
- @include_directive = JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true)
- @fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields))
- end
-
- # {http://jsonapi.org/format/#crud Requests are transactional, i.e. success or failure}
- # {http://jsonapi.org/format/#document-top-level data and errors MUST NOT coexist in the same document.}
- def serializable_hash(*)
- document = if serializer.success?
- success_document
- else
- failure_document
- end
- self.class.transform_key_casing!(document, instance_options)
- end
-
- def fragment_cache(cached_hash, non_cached_hash)
- root = !instance_options.include?(:include)
- self.class.fragment_cache(cached_hash, non_cached_hash, root)
- end
-
- # {http://jsonapi.org/format/#document-top-level Primary data}
- # definition:
- # ☐ toplevel_data (required)
- # ☐ toplevel_included
- # ☑ toplevel_meta
- # ☑ toplevel_links
- # ☑ toplevel_jsonapi
- # structure:
- # {
- # data: toplevel_data,
- # included: toplevel_included,
- # meta: toplevel_meta,
- # links: toplevel_links,
- # jsonapi: toplevel_jsonapi
- # }.reject! {|_,v| v.nil? }
- # rubocop:disable Metrics/CyclomaticComplexity
- def success_document
- is_collection = serializer.respond_to?(:each)
- serializers = is_collection ? serializer : [serializer]
- primary_data, included = resource_objects_for(serializers)
-
- hash = {}
- # toplevel_data
- # definition:
- # oneOf
- # resource
- # array of unique items of type 'resource'
- # null
- #
- # description:
- # The document's "primary data" is a representation of the resource or collection of resources
- # targeted by a request.
- #
- # Singular: the resource object.
- #
- # Collection: one of an array of resource objects, an array of resource identifier objects, or
- # an empty array ([]), for requests that target resource collections.
- #
- # None: null if the request is one that might correspond to a single resource, but doesn't currently.
- # structure:
- # if serializable_resource.resource?
- # resource
- # elsif serializable_resource.collection?
- # [
- # resource,
- # resource
- # ]
- # else
- # nil
- # end
- hash[:data] = is_collection ? primary_data : primary_data[0]
- # toplevel_included
- # alias included
- # definition:
- # array of unique items of type 'resource'
- #
- # description:
- # To reduce the number of HTTP requests, servers **MAY** allow
- # responses that include related resources along with the requested primary
- # resources. Such responses are called "compound documents".
- # structure:
- # [
- # resource,
- # resource
- # ]
- hash[:included] = included if included.any?
-
- Jsonapi.add!(hash)
-
- if instance_options[:links]
- hash[:links] ||= {}
- hash[:links].update(instance_options[:links])
- end
-
- if is_collection && serializer.paginated?
- hash[:links] ||= {}
- hash[:links].update(pagination_links_for(serializer))
- end
-
- hash[:meta] = instance_options[:meta] unless instance_options[:meta].blank?
-
- hash
- end
- # rubocop:enable Metrics/CyclomaticComplexity
-
- # {http://jsonapi.org/format/#errors JSON API Errors}
- # TODO: look into caching
- # definition:
- # ☑ toplevel_errors array (required)
- # ☐ toplevel_meta
- # ☐ toplevel_jsonapi
- # structure:
- # {
- # errors: toplevel_errors,
- # meta: toplevel_meta,
- # jsonapi: toplevel_jsonapi
- # }.reject! {|_,v| v.nil? }
- # prs:
- # https://github.com/rails-api/active_model_serializers/pull/1004
- def failure_document
- hash = {}
- # PR Please :)
- # Jsonapi.add!(hash)
-
- # toplevel_errors
- # definition:
- # array of unique items of type 'error'
- # structure:
- # [
- # error,
- # error
- # ]
- if serializer.respond_to?(:each)
- hash[:errors] = serializer.flat_map do |error_serializer|
- Error.resource_errors(error_serializer, instance_options)
- end
- else
- hash[:errors] = Error.resource_errors(serializer, instance_options)
- end
- hash
- end
-
- protected
-
- attr_reader :fieldset
-
- private
-
- # {http://jsonapi.org/format/#document-resource-objects Primary data}
- # resource
- # definition:
- # JSON Object
- #
- # properties:
- # type (required) : String
- # id (required) : String
- # attributes
- # relationships
- # links
- # meta
- #
- # description:
- # "Resource objects" appear in a JSON API document to represent resources
- # structure:
- # {
- # type: 'admin--some-user',
- # id: '1336',
- # attributes: attributes,
- # relationships: relationships,
- # links: links,
- # meta: meta,
- # }.reject! {|_,v| v.nil? }
- # prs:
- # type
- # https://github.com/rails-api/active_model_serializers/pull/1122
- # [x] https://github.com/rails-api/active_model_serializers/pull/1213
- # https://github.com/rails-api/active_model_serializers/pull/1216
- # https://github.com/rails-api/active_model_serializers/pull/1029
- # links
- # [x] https://github.com/rails-api/active_model_serializers/pull/1246
- # [x] url helpers https://github.com/rails-api/active_model_serializers/issues/1269
- # meta
- # [x] https://github.com/rails-api/active_model_serializers/pull/1340
- def resource_objects_for(serializers)
- @primary = []
- @included = []
- @resource_identifiers = Set.new
- serializers.each { |serializer| process_resource(serializer, true, @include_directive) }
- serializers.each { |serializer| process_relationships(serializer, @include_directive) }
-
- [@primary, @included]
- end
-
- def process_resource(serializer, primary, include_slice = {})
- resource_identifier = ResourceIdentifier.new(serializer, instance_options).as_json
- return false unless @resource_identifiers.add?(resource_identifier)
-
- resource_object = resource_object_for(serializer, include_slice)
- if primary
- @primary << resource_object
- else
- @included << resource_object
- end
-
- true
- end
-
- def process_relationships(serializer, include_slice)
- serializer.associations(include_slice).each do |association|
- # TODO(BF): Process relationship without evaluating lazy_association
- process_relationship(association.lazy_association.serializer, include_slice[association.key])
- end
- end
-
- def process_relationship(serializer, include_slice)
- if serializer.respond_to?(:each)
- serializer.each { |s| process_relationship(s, include_slice) }
- return
- end
- return unless serializer && serializer.object
- return unless process_resource(serializer, false, include_slice)
-
- process_relationships(serializer, include_slice)
- end
-
- # {http://jsonapi.org/format/#document-resource-object-attributes Document Resource Object Attributes}
- # attributes
- # definition:
- # JSON Object
- #
- # patternProperties:
- # ^(?!relationships$|links$)\\w[-\\w_]*$
- #
- # description:
- # Members of the attributes object ("attributes") represent information about the resource
- # object in which it's defined.
- # Attributes may contain any valid JSON value
- # structure:
- # {
- # foo: 'bar'
- # }
- def attributes_for(serializer, fields)
- serializer.attributes(fields).except(:id)
- end
-
- # {http://jsonapi.org/format/#document-resource-objects Document Resource Objects}
- def resource_object_for(serializer, include_slice = {})
- resource_object = data_for(serializer, include_slice)
-
- # toplevel_links
- # definition:
- # allOf
- # ☐ links
- # ☐ pagination
- #
- # description:
- # Link members related to the primary data.
- # structure:
- # links.merge!(pagination)
- # prs:
- # https://github.com/rails-api/active_model_serializers/pull/1247
- # https://github.com/rails-api/active_model_serializers/pull/1018
- if (links = links_for(serializer)).any?
- resource_object ||= {}
- resource_object[:links] = links
- end
-
- # toplevel_meta
- # alias meta
- # definition:
- # meta
- # structure
- # {
- # :'git-ref' => 'abc123'
- # }
- if (meta = meta_for(serializer)).present?
- resource_object ||= {}
- resource_object[:meta] = meta
- end
-
- resource_object
- end
-
- def data_for(serializer, include_slice)
- data = serializer.fetch(self) do
- resource_object = ResourceIdentifier.new(serializer, instance_options).as_json
- break nil if resource_object.nil?
-
- requested_fields = fieldset && fieldset.fields_for(resource_object[:type])
- attributes = attributes_for(serializer, requested_fields)
- resource_object[:attributes] = attributes if attributes.any?
- resource_object
- end
- data.tap do |resource_object|
- next if resource_object.nil?
- # NOTE(BF): the attributes are cached above, separately from the relationships, below.
- requested_associations = fieldset.fields_for(resource_object[:type]) || '*'
- relationships = relationships_for(serializer, requested_associations, include_slice)
- resource_object[:relationships] = relationships if relationships.any?
- end
- end
-
- # {http://jsonapi.org/format/#document-resource-object-relationships Document Resource Object Relationship}
- # relationships
- # definition:
- # JSON Object
- #
- # patternProperties:
- # ^\\w[-\\w_]*$"
- #
- # properties:
- # data : relationshipsData
- # links
- # meta
- #
- # description:
- #
- # Members of the relationships object ("relationships") represent references from the
- # resource object in which it's defined to other resource objects."
- # structure:
- # {
- # links: links,
- # meta: meta,
- # data: relationshipsData
- # }.reject! {|_,v| v.nil? }
- #
- # prs:
- # links
- # [x] https://github.com/rails-api/active_model_serializers/pull/1454
- # meta
- # [x] https://github.com/rails-api/active_model_serializers/pull/1454
- # polymorphic
- # [ ] https://github.com/rails-api/active_model_serializers/pull/1420
- #
- # relationshipsData
- # definition:
- # oneOf
- # relationshipToOne
- # relationshipToMany
- #
- # description:
- # Member, whose value represents "resource linkage"
- # structure:
- # if has_one?
- # relationshipToOne
- # else
- # relationshipToMany
- # end
- #
- # definition:
- # anyOf
- # null
- # linkage
- #
- # relationshipToOne
- # description:
- #
- # References to other resource objects in a to-one ("relationship"). Relationships can be
- # specified by including a member in a resource's links object.
- #
- # None: Describes an empty to-one relationship.
- # structure:
- # if has_related?
- # linkage
- # else
- # nil
- # end
- #
- # relationshipToMany
- # definition:
- # array of unique items of type 'linkage'
- #
- # description:
- # An array of objects each containing "type" and "id" members for to-many relationships
- # structure:
- # [
- # linkage,
- # linkage
- # ]
- # prs:
- # polymorphic
- # [ ] https://github.com/rails-api/active_model_serializers/pull/1282
- #
- # linkage
- # definition:
- # type (required) : String
- # id (required) : String
- # meta
- #
- # description:
- # The "type" and "id" to non-empty members.
- # structure:
- # {
- # type: 'required-type',
- # id: 'required-id',
- # meta: meta
- # }.reject! {|_,v| v.nil? }
- def relationships_for(serializer, requested_associations, include_slice)
- include_directive = JSONAPI::IncludeDirective.new(
- requested_associations,
- allow_wildcard: true
- )
- serializer.associations(include_directive, include_slice).each_with_object({}) do |association, hash|
- hash[association.key] = Relationship.new(serializer, instance_options, association).as_json
- end
- end
-
- # {http://jsonapi.org/format/#document-links Document Links}
- # links
- # definition:
- # JSON Object
- #
- # properties:
- # self : URI
- # related : link
- #
- # description:
- # A resource object **MAY** contain references to other resource objects ("relationships").
- # Relationships may be to-one or to-many. Relationships can be specified by including a member
- # in a resource's links object.
- #
- # A `self` member’s value is a URL for the relationship itself (a "relationship URL"). This
- # URL allows the client to directly manipulate the relationship. For example, it would allow
- # a client to remove an `author` from an `article` without deleting the people resource
- # itself.
- # structure:
- # {
- # self: 'http://example.com/etc',
- # related: link
- # }.reject! {|_,v| v.nil? }
- def links_for(serializer)
- serializer._links.each_with_object({}) do |(name, value), hash|
- result = Link.new(serializer, value).as_json
- hash[name] = result if result
- end
- end
-
- # {http://jsonapi.org/format/#fetching-pagination Pagination Links}
- # pagination
- # definition:
- # first : pageObject
- # last : pageObject
- # prev : pageObject
- # next : pageObject
- # structure:
- # {
- # first: pageObject,
- # last: pageObject,
- # prev: pageObject,
- # next: pageObject
- # }
- #
- # pageObject
- # definition:
- # oneOf
- # URI
- # null
- #
- # description:
- # The page of data
- # structure:
- # if has_page?
- # 'http://example.com/some-page?page[number][x]'
- # else
- # nil
- # end
- # prs:
- # https://github.com/rails-api/active_model_serializers/pull/1041
- def pagination_links_for(serializer)
- PaginationLinks.new(serializer.object, instance_options).as_json
- end
-
- # {http://jsonapi.org/format/#document-meta Docment Meta}
- def meta_for(serializer)
- Meta.new(serializer).as_json
- end
- end
- end
-end
-# rubocop:enable Style/AsciiComments
diff --git a/lib/active_model_serializers/adapter/json_api/deserialization.rb b/lib/active_model_serializers/adapter/json_api/deserialization.rb
deleted file mode 100644
index b79125ac..00000000
--- a/lib/active_model_serializers/adapter/json_api/deserialization.rb
+++ /dev/null
@@ -1,213 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- # NOTE(Experimental):
- # This is an experimental feature. Both the interface and internals could be subject
- # to changes.
- module Deserialization
- InvalidDocument = Class.new(ArgumentError)
-
- module_function
-
- # Transform a JSON API document, containing a single data object,
- # into a hash that is ready for ActiveRecord::Base.new() and such.
- # Raises InvalidDocument if the payload is not properly formatted.
- #
- # @param [Hash|ActionController::Parameters] document
- # @param [Hash] options
- # only: Array of symbols of whitelisted fields.
- # except: Array of symbols of blacklisted fields.
- # keys: Hash of translated keys (e.g. :author => :user).
- # polymorphic: Array of symbols of polymorphic fields.
- # @return [Hash]
- #
- # @example
- # document = {
- # data: {
- # id: 1,
- # type: 'post',
- # attributes: {
- # title: 'Title 1',
- # date: '2015-12-20'
- # },
- # associations: {
- # author: {
- # data: {
- # type: 'user',
- # id: 2
- # }
- # },
- # second_author: {
- # data: nil
- # },
- # comments: {
- # data: [{
- # type: 'comment',
- # id: 3
- # },{
- # type: 'comment',
- # id: 4
- # }]
- # }
- # }
- # }
- # }
- #
- # parse(document) #=>
- # # {
- # # title: 'Title 1',
- # # date: '2015-12-20',
- # # author_id: 2,
- # # second_author_id: nil
- # # comment_ids: [3, 4]
- # # }
- #
- # parse(document, only: [:title, :date, :author],
- # keys: { date: :published_at },
- # polymorphic: [:author]) #=>
- # # {
- # # title: 'Title 1',
- # # published_at: '2015-12-20',
- # # author_id: '2',
- # # author_type: 'people'
- # # }
- #
- def parse!(document, options = {})
- parse(document, options) do |invalid_payload, reason|
- fail InvalidDocument, "Invalid payload (#{reason}): #{invalid_payload}"
- end
- end
-
- # Same as parse!, but returns an empty hash instead of raising InvalidDocument
- # on invalid payloads.
- def parse(document, options = {})
- document = document.dup.permit!.to_h if document.is_a?(ActionController::Parameters)
-
- validate_payload(document) do |invalid_document, reason|
- yield invalid_document, reason if block_given?
- return {}
- end
-
- primary_data = document['data']
- attributes = primary_data['attributes'] || {}
- attributes['id'] = primary_data['id'] if primary_data['id']
- relationships = primary_data['relationships'] || {}
-
- filter_fields(attributes, options)
- filter_fields(relationships, options)
-
- hash = {}
- hash.merge!(parse_attributes(attributes, options))
- hash.merge!(parse_relationships(relationships, options))
-
- hash
- end
-
- # Checks whether a payload is compliant with the JSON API spec.
- #
- # @api private
- # rubocop:disable Metrics/CyclomaticComplexity
- def validate_payload(payload)
- unless payload.is_a?(Hash)
- yield payload, 'Expected hash'
- return
- end
-
- primary_data = payload['data']
- unless primary_data.is_a?(Hash)
- yield payload, { data: 'Expected hash' }
- return
- end
-
- attributes = primary_data['attributes'] || {}
- unless attributes.is_a?(Hash)
- yield payload, { data: { attributes: 'Expected hash or nil' } }
- return
- end
-
- relationships = primary_data['relationships'] || {}
- unless relationships.is_a?(Hash)
- yield payload, { data: { relationships: 'Expected hash or nil' } }
- return
- end
-
- relationships.each do |(key, value)|
- unless value.is_a?(Hash) && value.key?('data')
- yield payload, { data: { relationships: { key => 'Expected hash with :data key' } } }
- end
- end
- end
- # rubocop:enable Metrics/CyclomaticComplexity
-
- # @api private
- def filter_fields(fields, options)
- if (only = options[:only])
- fields.slice!(*Array(only).map(&:to_s))
- elsif (except = options[:except])
- fields.except!(*Array(except).map(&:to_s))
- end
- end
-
- # @api private
- def field_key(field, options)
- (options[:keys] || {}).fetch(field.to_sym, field).to_sym
- end
-
- # @api private
- def parse_attributes(attributes, options)
- transform_keys(attributes, options)
- .map { |(k, v)| { field_key(k, options) => v } }
- .reduce({}, :merge)
- end
-
- # Given an association name, and a relationship data attribute, build a hash
- # mapping the corresponding ActiveRecord attribute to the corresponding value.
- #
- # @example
- # parse_relationship(:comments, [{ 'id' => '1', 'type' => 'comments' },
- # { 'id' => '2', 'type' => 'comments' }],
- # {})
- # # => { :comment_ids => ['1', '2'] }
- # parse_relationship(:author, { 'id' => '1', 'type' => 'users' }, {})
- # # => { :author_id => '1' }
- # parse_relationship(:author, nil, {})
- # # => { :author_id => nil }
- # @param [Symbol] assoc_name
- # @param [Hash] assoc_data
- # @param [Hash] options
- # @return [Hash{Symbol, Object}]
- #
- # @api private
- def parse_relationship(assoc_name, assoc_data, options)
- prefix_key = field_key(assoc_name, options).to_s.singularize
- hash =
- if assoc_data.is_a?(Array)
- { "#{prefix_key}_ids".to_sym => assoc_data.map { |ri| ri['id'] } }
- else
- { "#{prefix_key}_id".to_sym => assoc_data ? assoc_data['id'] : nil }
- end
-
- polymorphic = (options[:polymorphic] || []).include?(assoc_name.to_sym)
- if polymorphic
- hash["#{prefix_key}_type".to_sym] = assoc_data.present? ? assoc_data['type'] : nil
- end
-
- hash
- end
-
- # @api private
- def parse_relationships(relationships, options)
- transform_keys(relationships, options)
- .map { |(k, v)| parse_relationship(k, v['data'], options) }
- .reduce({}, :merge)
- end
-
- # @api private
- def transform_keys(hash, options)
- transform = options[:key_transform] || :underscore
- CaseTransform.send(transform, hash)
- end
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/adapter/json_api/error.rb b/lib/active_model_serializers/adapter/json_api/error.rb
deleted file mode 100644
index c7b18716..00000000
--- a/lib/active_model_serializers/adapter/json_api/error.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- class JsonApi < Base
- module Error
- # rubocop:disable Style/AsciiComments
- UnknownSourceTypeError = Class.new(ArgumentError)
-
- # Builds a JSON API Errors Object
- # {http://jsonapi.org/format/#errors JSON API Errors}
- #
- # @param [ActiveModel::Serializer::ErrorSerializer] error_serializer
- # @return [Array>] i.e. attribute_name, [attribute_errors]
- def self.resource_errors(error_serializer, options)
- error_serializer.as_json.flat_map do |attribute_name, attribute_errors|
- attribute_name = JsonApi.send(:transform_key_casing!, attribute_name,
- options)
- attribute_error_objects(attribute_name, attribute_errors)
- end
- end
-
- # definition:
- # JSON Object
- #
- # properties:
- # ☐ id : String
- # ☐ status : String
- # ☐ code : String
- # ☐ title : String
- # ☑ detail : String
- # ☐ links
- # ☐ meta
- # ☑ error_source
- #
- # description:
- # id : A unique identifier for this particular occurrence of the problem.
- # status : The HTTP status code applicable to this problem, expressed as a string value
- # code : An application-specific error code, expressed as a string value.
- # title : A short, human-readable summary of the problem. It **SHOULD NOT** change from
- # occurrence to occurrence of the problem, except for purposes of localization.
- # detail : A human-readable explanation specific to this occurrence of the problem.
- # structure:
- # {
- # title: 'SystemFailure',
- # detail: 'something went terribly wrong',
- # status: '500'
- # }.merge!(errorSource)
- def self.attribute_error_objects(attribute_name, attribute_errors)
- attribute_errors.map do |attribute_error|
- {
- source: error_source(:pointer, attribute_name),
- detail: attribute_error
- }
- end
- end
-
- # errorSource
- # description:
- # oneOf
- # ☑ pointer : String
- # ☑ parameter : String
- #
- # description:
- # pointer: A JSON Pointer RFC6901 to the associated entity in the request document e.g. "/data"
- # for a primary data object, or "/data/attributes/title" for a specific attribute.
- # https://tools.ietf.org/html/rfc6901
- #
- # parameter: A string indicating which query parameter caused the error
- # structure:
- # if is_attribute?
- # {
- # pointer: '/data/attributes/red-button'
- # }
- # else
- # {
- # parameter: 'pres'
- # }
- # end
- def self.error_source(source_type, attribute_name)
- case source_type
- when :pointer
- {
- pointer: ActiveModelSerializers::JsonPointer.new(:attribute, attribute_name)
- }
- when :parameter
- {
- parameter: attribute_name
- }
- else
- fail UnknownSourceTypeError, "Unknown source type '#{source_type}' for attribute_name '#{attribute_name}'"
- end
- end
- # rubocop:enable Style/AsciiComments
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/adapter/json_api/jsonapi.rb b/lib/active_model_serializers/adapter/json_api/jsonapi.rb
deleted file mode 100644
index e94578af..00000000
--- a/lib/active_model_serializers/adapter/json_api/jsonapi.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- class JsonApi < Base
- # {http://jsonapi.org/format/#document-jsonapi-object Jsonapi Object}
-
- # toplevel_jsonapi
- # definition:
- # JSON Object
- #
- # properties:
- # version : String
- # meta
- #
- # description:
- # An object describing the server's implementation
- # structure:
- # {
- # version: ActiveModelSerializers.config.jsonapi_version,
- # meta: ActiveModelSerializers.config.jsonapi_toplevel_meta
- # }.reject! { |_, v| v.blank? }
- # prs:
- # https://github.com/rails-api/active_model_serializers/pull/1050
- module Jsonapi
- module_function
-
- def add!(hash)
- hash.merge!(object) if include_object?
- end
-
- def include_object?
- ActiveModelSerializers.config.jsonapi_include_toplevel_object
- end
-
- # TODO: see if we can cache this
- def object
- object = {
- jsonapi: {
- version: ActiveModelSerializers.config.jsonapi_version,
- meta: ActiveModelSerializers.config.jsonapi_toplevel_meta
- }
- }
- object[:jsonapi].reject! { |_, v| v.blank? }
-
- object
- end
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/adapter/json_api/link.rb b/lib/active_model_serializers/adapter/json_api/link.rb
deleted file mode 100644
index 64e15071..00000000
--- a/lib/active_model_serializers/adapter/json_api/link.rb
+++ /dev/null
@@ -1,83 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- # link
- # definition:
- # oneOf
- # linkString
- # linkObject
- #
- # description:
- # A link **MUST** be represented as either: a string containing the link's URL or a link
- # object."
- # structure:
- # if href?
- # linkString
- # else
- # linkObject
- # end
- #
- # linkString
- # definition:
- # URI
- #
- # description:
- # A string containing the link's URL.
- # structure:
- # 'http://example.com/link-string'
- #
- # linkObject
- # definition:
- # JSON Object
- #
- # properties:
- # href (required) : URI
- # meta
- # structure:
- # {
- # href: 'http://example.com/link-object',
- # meta: meta,
- # }.reject! {|_,v| v.nil? }
- class Link
- include SerializationContext::UrlHelpers
-
- def initialize(serializer, value)
- @_routes ||= nil # handles warning
- # actionpack-4.0.13/lib/action_dispatch/routing/route_set.rb:417: warning: instance variable @_routes not initialized
- @object = serializer.object
- @scope = serializer.scope
- # Use the return value of the block unless it is nil.
- if value.respond_to?(:call)
- @value = instance_eval(&value)
- else
- @value = value
- end
- end
-
- def href(value)
- @href = value
- nil
- end
-
- def meta(value)
- @meta = value
- nil
- end
-
- def as_json
- return @value if @value
-
- hash = {}
- hash[:href] = @href if defined?(@href)
- hash[:meta] = @meta if defined?(@meta)
-
- hash.any? ? hash : nil
- end
-
- protected
-
- attr_reader :object, :scope
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/adapter/json_api/meta.rb b/lib/active_model_serializers/adapter/json_api/meta.rb
deleted file mode 100644
index d889b3eb..00000000
--- a/lib/active_model_serializers/adapter/json_api/meta.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- # meta
- # definition:
- # JSON Object
- #
- # description:
- # Non-standard meta-information that can not be represented as an attribute or relationship.
- # structure:
- # {
- # attitude: 'adjustable'
- # }
- class Meta
- def initialize(serializer)
- @object = serializer.object
- @scope = serializer.scope
-
- # Use the return value of the block unless it is nil.
- if serializer._meta.respond_to?(:call)
- @value = instance_eval(&serializer._meta)
- else
- @value = serializer._meta
- end
- end
-
- def as_json
- @value
- end
-
- protected
-
- attr_reader :object, :scope
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/adapter/json_api/pagination_links.rb b/lib/active_model_serializers/adapter/json_api/pagination_links.rb
deleted file mode 100644
index b15f5ba6..00000000
--- a/lib/active_model_serializers/adapter/json_api/pagination_links.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- class JsonApi < Base
- class PaginationLinks
- MissingSerializationContextError = Class.new(KeyError)
- FIRST_PAGE = 1
-
- attr_reader :collection, :context
-
- def initialize(collection, adapter_options)
- @collection = collection
- @adapter_options = adapter_options
- @context = adapter_options.fetch(:serialization_context) do
- fail MissingSerializationContextError, <<-EOF.freeze
- JsonApi::PaginationLinks requires a ActiveModelSerializers::SerializationContext.
- Please pass a ':serialization_context' option or
- override CollectionSerializer#paginated? to return 'false'.
- EOF
- end
- end
-
- def as_json
- per_page = collection.try(:per_page) || collection.try(:limit_value) || collection.size
- pages_from.each_with_object({}) do |(key, value), hash|
- params = query_parameters.merge(page: { number: value, size: per_page }).to_query
-
- hash[key] = "#{url(adapter_options)}?#{params}"
- end
- end
-
- protected
-
- attr_reader :adapter_options
-
- private
-
- def pages_from
- return {} if collection.total_pages <= FIRST_PAGE
-
- {}.tap do |pages|
- pages[:self] = collection.current_page
-
- unless collection.current_page == FIRST_PAGE
- pages[:first] = FIRST_PAGE
- pages[:prev] = collection.current_page - FIRST_PAGE
- end
-
- unless collection.current_page == collection.total_pages
- pages[:next] = collection.current_page + FIRST_PAGE
- pages[:last] = collection.total_pages
- end
- end
- end
-
- def url(options)
- @url ||= options.fetch(:links, {}).fetch(:self, nil) || request_url
- end
-
- def request_url
- @request_url ||= context.request_url
- end
-
- def query_parameters
- @query_parameters ||= context.query_parameters
- end
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/adapter/json_api/relationship.rb b/lib/active_model_serializers/adapter/json_api/relationship.rb
deleted file mode 100644
index 5d7399a3..00000000
--- a/lib/active_model_serializers/adapter/json_api/relationship.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class Relationship
- # {http://jsonapi.org/format/#document-resource-object-related-resource-links Document Resource Object Related Resource Links}
- # {http://jsonapi.org/format/#document-links Document Links}
- # {http://jsonapi.org/format/#document-resource-object-linkage Document Resource Relationship Linkage}
- # {http://jsonapi.org/format/#document-meta Document Meta}
- def initialize(parent_serializer, serializable_resource_options, association)
- @parent_serializer = parent_serializer
- @association = association
- @serializable_resource_options = serializable_resource_options
- end
-
- def as_json
- hash = {}
-
- hash[:data] = data_for(association) if association.include_data?
-
- links = links_for(association)
- hash[:links] = links if links.any?
-
- meta = meta_for(association)
- hash[:meta] = meta if meta
- hash[:meta] = {} if hash.empty?
-
- hash
- end
-
- protected
-
- attr_reader :parent_serializer, :serializable_resource_options, :association
-
- private
-
- # TODO(BF): Avoid db hit on belong_to_ releationship by using foreign_key on self
- def data_for(association)
- if association.collection?
- data_for_many(association)
- else
- data_for_one(association)
- end
- end
-
- def data_for_one(association)
- if association.belongs_to? &&
- parent_serializer.object.respond_to?(association.reflection.foreign_key)
- id = parent_serializer.object.send(association.reflection.foreign_key)
- type = association.reflection.type.to_s
- ResourceIdentifier.for_type_with_id(type, id, serializable_resource_options)
- else
- # TODO(BF): Process relationship without evaluating lazy_association
- serializer = association.lazy_association.serializer
- if (virtual_value = association.virtual_value)
- virtual_value
- elsif serializer && association.object
- ResourceIdentifier.new(serializer, serializable_resource_options).as_json
- else
- nil
- end
- end
- end
-
- def data_for_many(association)
- # TODO(BF): Process relationship without evaluating lazy_association
- collection_serializer = association.lazy_association.serializer
- if collection_serializer.respond_to?(:each)
- collection_serializer.map do |serializer|
- ResourceIdentifier.new(serializer, serializable_resource_options).as_json
- end
- elsif (virtual_value = association.virtual_value)
- virtual_value
- else
- []
- end
- end
-
- def links_for(association)
- association.links.each_with_object({}) do |(key, value), hash|
- result = Link.new(parent_serializer, value).as_json
- hash[key] = result if result
- end
- end
-
- def meta_for(association)
- meta = association.meta
- meta.respond_to?(:call) ? parent_serializer.instance_eval(&meta) : meta
- end
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/adapter/json_api/resource_identifier.rb b/lib/active_model_serializers/adapter/json_api/resource_identifier.rb
deleted file mode 100644
index 3a235f2b..00000000
--- a/lib/active_model_serializers/adapter/json_api/resource_identifier.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class ResourceIdentifier
- def self.type_for(class_name, serializer_type = nil, transform_options = {})
- if serializer_type
- raw_type = serializer_type
- else
- inflection =
- if ActiveModelSerializers.config.jsonapi_resource_type == :singular
- :singularize
- else
- :pluralize
- end
-
- raw_type = class_name.underscore
- raw_type = ActiveSupport::Inflector.public_send(inflection, raw_type)
- raw_type
- .gsub!('/'.freeze, ActiveModelSerializers.config.jsonapi_namespace_separator)
- raw_type
- end
- JsonApi.send(:transform_key_casing!, raw_type, transform_options)
- end
-
- def self.for_type_with_id(type, id, options)
- return nil if id.blank?
- {
- id: id.to_s,
- type: type_for(:no_class_needed, type, options)
- }
- end
-
- # {http://jsonapi.org/format/#document-resource-identifier-objects Resource Identifier Objects}
- def initialize(serializer, options)
- @id = id_for(serializer)
- @type = type_for(serializer, options)
- end
-
- def as_json
- return nil if id.blank?
- { id: id, type: type }
- end
-
- protected
-
- attr_reader :id, :type
-
- private
-
- def type_for(serializer, transform_options)
- self.class.type_for(serializer.object.class.name, serializer._type, transform_options)
- end
-
- def id_for(serializer)
- serializer.read_attribute_for_serialization(:id).to_s
- end
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/adapter/null.rb b/lib/active_model_serializers/adapter/null.rb
deleted file mode 100644
index 9e5faf5c..00000000
--- a/lib/active_model_serializers/adapter/null.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module ActiveModelSerializers
- module Adapter
- class Null < Base
- def serializable_hash(*)
- {}
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/callbacks.rb b/lib/active_model_serializers/callbacks.rb
deleted file mode 100644
index 71237e4a..00000000
--- a/lib/active_model_serializers/callbacks.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-# Adapted from
-# https://github.com/rails/rails/blob/7f18ea14c8/activejob/lib/active_job/callbacks.rb
-require 'active_support/callbacks'
-
-module ActiveModelSerializers
- # = ActiveModelSerializers Callbacks
- #
- # ActiveModelSerializers provides hooks during the life cycle of serialization and
- # allow you to trigger logic. Available callbacks are:
- #
- # * around_render
- #
- module Callbacks
- extend ActiveSupport::Concern
- include ActiveSupport::Callbacks
-
- included do
- define_callbacks :render
- end
-
- # These methods will be included into any ActiveModelSerializers object, adding
- # callbacks for +render+.
- module ClassMethods
- # Defines a callback that will get called around the render method,
- # whether it is as_json, to_json, or serializable_hash
- #
- # class ActiveModelSerializers::SerializableResource
- # include ActiveModelSerializers::Callbacks
- #
- # around_render do |args, block|
- # tag_logger do
- # notify_render do
- # block.call(args)
- # end
- # end
- # end
- #
- # def as_json
- # run_callbacks :render do
- # adapter.as_json
- # end
- # end
- # # Note: So that we can re-use the instrumenter for as_json, to_json, and
- # # serializable_hash, we aren't using the usual format, which would be:
- # # def render(args)
- # # adapter.as_json
- # # end
- # end
- #
- def around_render(*filters, &blk)
- set_callback(:render, :around, *filters, &blk)
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/deprecate.rb b/lib/active_model_serializers/deprecate.rb
deleted file mode 100644
index e173321d..00000000
--- a/lib/active_model_serializers/deprecate.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-##
-# Provides a single method +deprecate+ to be used to declare when
-# something is going away.
-#
-# class Legacy
-# def self.klass_method
-# # ...
-# end
-#
-# def instance_method
-# # ...
-# end
-#
-# extend ActiveModelSerializers::Deprecate
-# deprecate :instance_method, "ActiveModelSerializers::NewPlace#new_method"
-#
-# class << self
-# extend ActiveModelSerializers::Deprecate
-# deprecate :klass_method, :none
-# end
-# end
-#
-# Adapted from https://github.com/rubygems/rubygems/blob/1591331/lib/rubygems/deprecate.rb
-module ActiveModelSerializers
- module Deprecate
- ##
- # Simple deprecation method that deprecates +name+ by wrapping it up
- # in a dummy method. It warns on each call to the dummy method
- # telling the user of +replacement+ (unless +replacement+ is :none) that it is planned to go away.
-
- def deprecate(name, replacement)
- old = "_deprecated_#{name}"
- alias_method old, name
- class_eval do
- define_method(name) do |*args, &block|
- target = is_a?(Module) ? "#{self}." : "#{self.class}#"
- msg = ["NOTE: #{target}#{name} is deprecated",
- replacement == :none ? ' with no replacement' : "; use #{replacement} instead",
- "\n#{target}#{name} called from #{ActiveModelSerializers.location_of_caller.join(':')}"]
- warn "#{msg.join}."
- send old, *args, &block
- end
- end
- end
-
- def delegate_and_deprecate(method, delegee)
- delegate method, to: delegee
- deprecate method, "#{delegee.name}."
- end
-
- module_function :deprecate
- module_function :delegate_and_deprecate
- end
-end
diff --git a/lib/active_model_serializers/deserialization.rb b/lib/active_model_serializers/deserialization.rb
deleted file mode 100644
index 878dd98d..00000000
--- a/lib/active_model_serializers/deserialization.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module ActiveModelSerializers
- module Deserialization
- module_function
-
- def jsonapi_parse(*args)
- Adapter::JsonApi::Deserialization.parse(*args)
- end
-
- # :nocov:
- def jsonapi_parse!(*args)
- Adapter::JsonApi::Deserialization.parse!(*args)
- end
- # :nocov:
- end
-end
diff --git a/lib/active_model_serializers/json_pointer.rb b/lib/active_model_serializers/json_pointer.rb
deleted file mode 100644
index a262f3b2..00000000
--- a/lib/active_model_serializers/json_pointer.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-module ActiveModelSerializers
- module JsonPointer
- module_function
-
- POINTERS = {
- attribute: '/data/attributes/%s'.freeze,
- primary_data: '/data%s'.freeze
- }.freeze
-
- def new(pointer_type, value = nil)
- format(POINTERS[pointer_type], value)
- end
- end
-end
diff --git a/lib/active_model_serializers/logging.rb b/lib/active_model_serializers/logging.rb
deleted file mode 100644
index 943e937e..00000000
--- a/lib/active_model_serializers/logging.rb
+++ /dev/null
@@ -1,122 +0,0 @@
-##
-# ActiveModelSerializers::Logging
-#
-# https://github.com/rails/rails/blob/280654ef88/activejob/lib/active_job/logging.rb
-#
-module ActiveModelSerializers
- module Logging
- RENDER_EVENT = 'render.active_model_serializers'.freeze
- extend ActiveSupport::Concern
-
- included do
- include ActiveModelSerializers::Callbacks
- extend Macros
- instrument_rendering
- end
-
- module ClassMethods
- def instrument_rendering
- around_render do |args, block|
- tag_logger do
- notify_render do
- block.call(args)
- end
- end
- end
- end
- end
-
- # Macros that can be used to customize the logging of class or instance methods,
- # by extending the class or its singleton.
- #
- # Adapted from:
- # https://github.com/rubygems/rubygems/blob/cb28f5e991/lib/rubygems/deprecate.rb
- #
- # Provides a single method +notify+ to be used to declare when
- # something a method notifies, with the argument +callback_name+ of the notification callback.
- #
- # class Adapter
- # def self.klass_method
- # # ...
- # end
- #
- # def instance_method
- # # ...
- # end
- #
- # include ActiveModelSerializers::Logging::Macros
- # notify :instance_method, :render
- #
- # class << self
- # extend ActiveModelSerializers::Logging::Macros
- # notify :klass_method, :render
- # end
- # end
- module Macros
- ##
- # Simple notify method that wraps up +name+
- # in a dummy method. It notifies on with the +callback_name+ notifier on
- # each call to the dummy method, telling what the current serializer and adapter
- # are being rendered.
- # Adapted from:
- # https://github.com/rubygems/rubygems/blob/cb28f5e991/lib/rubygems/deprecate.rb
- def notify(name, callback_name)
- class_eval do
- old = "_notifying_#{callback_name}_#{name}"
- alias_method old, name
- define_method name do |*args, &block|
- run_callbacks callback_name do
- send old, *args, &block
- end
- end
- end
- end
- end
-
- def notify_render(*)
- event_name = RENDER_EVENT
- ActiveSupport::Notifications.instrument(event_name, notify_render_payload) do
- yield
- end
- end
-
- def notify_render_payload
- {
- serializer: serializer || ActiveModel::Serializer::Null,
- adapter: adapter || ActiveModelSerializers::Adapter::Null
- }
- end
-
- private
-
- def tag_logger(*tags)
- if ActiveModelSerializers.logger.respond_to?(:tagged)
- tags.unshift 'active_model_serializers'.freeze unless logger_tagged_by_active_model_serializers?
- ActiveModelSerializers.logger.tagged(*tags) { yield }
- else
- yield
- end
- end
-
- def logger_tagged_by_active_model_serializers?
- ActiveModelSerializers.logger.formatter.current_tags.include?('active_model_serializers'.freeze)
- end
-
- class LogSubscriber < ActiveSupport::LogSubscriber
- def render(event)
- info do
- serializer = event.payload[:serializer]
- adapter = event.payload[:adapter]
- duration = event.duration.round(2)
- "Rendered #{serializer.name} with #{adapter.class} (#{duration}ms)"
- end
- end
-
- def logger
- ActiveModelSerializers.logger
- end
- end
- end
-end
-
-ActiveModelSerializers::Logging::LogSubscriber.attach_to :active_model_serializers
diff --git a/lib/active_model_serializers/lookup_chain.rb b/lib/active_model_serializers/lookup_chain.rb
deleted file mode 100644
index 25db8e13..00000000
--- a/lib/active_model_serializers/lookup_chain.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-module ActiveModelSerializers
- module LookupChain
- # Standard appending of Serializer to the resource name.
- #
- # Example:
- # Author => AuthorSerializer
- BY_RESOURCE = lambda do |resource_class, _serializer_class, _namespace|
- serializer_from(resource_class)
- end
-
- # Uses the namespace of the resource to find the serializer
- #
- # Example:
- # British::Author => British::AuthorSerializer
- BY_RESOURCE_NAMESPACE = lambda do |resource_class, _serializer_class, _namespace|
- resource_namespace = namespace_for(resource_class)
- serializer_name = serializer_from(resource_class)
-
- "#{resource_namespace}::#{serializer_name}"
- end
-
- # Uses the controller namespace of the resource to find the serializer
- #
- # Example:
- # Api::V3::AuthorsController => Api::V3::AuthorSerializer
- BY_NAMESPACE = lambda do |resource_class, _serializer_class, namespace|
- resource_name = resource_class_name(resource_class)
- namespace ? "#{namespace}::#{resource_name}Serializer" : nil
- end
-
- # Allows for serializers to be defined in parent serializers
- # - useful if a relationship only needs a different set of attributes
- # than if it were rendered independently.
- #
- # Example:
- # class BlogSerializer < ActiveModel::Serializer
- # class AuthorSerialier < ActiveModel::Serializer
- # ...
- # end
- #
- # belongs_to :author
- # ...
- # end
- #
- # The belongs_to relationship would be rendered with
- # BlogSerializer::AuthorSerialier
- BY_PARENT_SERIALIZER = lambda do |resource_class, serializer_class, _namespace|
- return if serializer_class == ActiveModel::Serializer
-
- serializer_name = serializer_from(resource_class)
- "#{serializer_class}::#{serializer_name}"
- end
-
- DEFAULT = [
- BY_PARENT_SERIALIZER,
- BY_NAMESPACE,
- BY_RESOURCE_NAMESPACE,
- BY_RESOURCE
- ].freeze
-
- module_function
-
- def namespace_for(klass)
- klass.name.deconstantize
- end
-
- def resource_class_name(klass)
- klass.name.demodulize
- end
-
- def serializer_from_resource_name(name)
- "#{name}Serializer"
- end
-
- def serializer_from(klass)
- name = resource_class_name(klass)
- serializer_from_resource_name(name)
- end
- end
-end
diff --git a/lib/active_model_serializers/model.rb b/lib/active_model_serializers/model.rb
deleted file mode 100644
index 2ff3d60c..00000000
--- a/lib/active_model_serializers/model.rb
+++ /dev/null
@@ -1,130 +0,0 @@
-# ActiveModelSerializers::Model is a convenient superclass for making your models
-# from Plain-Old Ruby Objects (PORO). It also serves as a reference implementation
-# that satisfies ActiveModel::Serializer::Lint::Tests.
-require 'active_support/core_ext/hash'
-module ActiveModelSerializers
- class Model
- include ActiveModel::Serializers::JSON
- include ActiveModel::Model
-
- # Declare names of attributes to be included in +attributes+ hash.
- # Is only available as a class-method since the ActiveModel::Serialization mixin in Rails
- # uses an +attribute_names+ local variable, which may conflict if we were to add instance methods here.
- #
- # @overload attribute_names
- # @return [Array]
- class_attribute :attribute_names, instance_writer: false, instance_reader: false
- # Initialize +attribute_names+ for all subclasses. The array is usually
- # mutated in the +attributes+ method, but can be set directly, as well.
- self.attribute_names = []
-
- # Easily declare instance attributes with setters and getters for each.
- #
- # To initialize an instance, all attributes must have setters.
- # However, the hash returned by +attributes+ instance method will ALWAYS
- # be the value of the initial attributes, regardless of what accessors are defined.
- # The only way to change the change the attributes after initialization is
- # to mutate the +attributes+ directly.
- # Accessor methods do NOT mutate the attributes. (This is a bug).
- #
- # @note For now, the Model only supports the notion of 'attributes'.
- # In the tests, there is a special Model that also supports 'associations'. This is
- # important so that we can add accessors for values that should not appear in the
- # attributes hash when modeling associations. It is not yet clear if it
- # makes sense for a PORO to have associations outside of the tests.
- #
- # @overload attributes(names)
- # @param names [Array]
- # @param name [String, Symbol]
- def self.attributes(*names)
- self.attribute_names |= names.map(&:to_sym)
- # Silence redefinition of methods warnings
- ActiveModelSerializers.silence_warnings do
- attr_accessor(*names)
- end
- end
-
- # Opt-in to breaking change
- def self.derive_attributes_from_names_and_fix_accessors
- unless included_modules.include?(DeriveAttributesFromNamesAndFixAccessors)
- prepend(DeriveAttributesFromNamesAndFixAccessors)
- end
- end
-
- module DeriveAttributesFromNamesAndFixAccessors
- def self.included(base)
- # NOTE that +id+ will always be in +attributes+.
- base.attributes :id
- end
-
- # Override the +attributes+ method so that the hash is derived from +attribute_names+.
- #
- # The fields in +attribute_names+ determines the returned hash.
- # +attributes+ are returned frozen to prevent any expectations that mutation affects
- # the actual values in the model.
- def attributes
- self.class.attribute_names.each_with_object({}) do |attribute_name, result|
- result[attribute_name] = public_send(attribute_name).freeze
- end.with_indifferent_access.freeze
- end
- end
-
- # Support for validation and other ActiveModel::Errors
- # @return [ActiveModel::Errors]
- attr_reader :errors
-
- # (see #updated_at)
- attr_writer :updated_at
-
- # The only way to change the attributes of an instance is to directly mutate the attributes.
- # @example
- #
- # model.attributes[:foo] = :bar
- # @return [Hash]
- attr_reader :attributes
-
- # @param attributes [Hash]
- def initialize(attributes = {})
- attributes ||= {} # protect against nil
- @attributes = attributes.symbolize_keys.with_indifferent_access
- @errors = ActiveModel::Errors.new(self)
- super
- end
-
- # Defaults to the downcased model name.
- # This probably isn't a good default, since it's not a unique instance identifier,
- # but that's what is currently implemented \_('-')_/.
- #
- # @note Though +id+ is defined, it will only show up
- # in +attributes+ when it is passed in to the initializer or added to +attributes+,
- # such as attributes[:id] = 5.
- # @return [String, Numeric, Symbol]
- def id
- attributes.fetch(:id) do
- defined?(@id) ? @id : self.class.model_name.name && self.class.model_name.name.downcase
- end
- end
-
- # When not set, defaults to the time the file was modified.
- #
- # @note Though +updated_at+ and +updated_at=+ are defined, it will only show up
- # in +attributes+ when it is passed in to the initializer or added to +attributes+,
- # such as attributes[:updated_at] = Time.current.
- # @return [String, Numeric, Time]
- def updated_at
- attributes.fetch(:updated_at) do
- defined?(@updated_at) ? @updated_at : File.mtime(__FILE__)
- end
- end
-
- # To customize model behavior, this method must be redefined. However,
- # there are other ways of setting the +cache_key+ a serializer uses.
- # @return [String]
- def cache_key
- ActiveSupport::Cache.expand_cache_key([
- self.class.model_name.name.downcase,
- "#{id}-#{updated_at.strftime('%Y%m%d%H%M%S%9N')}"
- ].compact)
- end
- end
-end
diff --git a/lib/active_model_serializers/railtie.rb b/lib/active_model_serializers/railtie.rb
deleted file mode 100644
index d6843c9c..00000000
--- a/lib/active_model_serializers/railtie.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-require 'rails/railtie'
-require 'action_controller'
-require 'action_controller/railtie'
-require 'action_controller/serialization'
-
-module ActiveModelSerializers
- class Railtie < Rails::Railtie
- config.to_prepare do
- ActiveModel::Serializer.serializers_cache.clear
- end
-
- initializer 'active_model_serializers.action_controller' do
- ActiveSupport.on_load(:action_controller) do
- include(::ActionController::Serialization)
- end
- end
-
- initializer 'active_model_serializers.prepare_serialization_context' do
- SerializationContext.url_helpers = Rails.application.routes.url_helpers
- SerializationContext.default_url_options = Rails.application.routes.default_url_options
- end
-
- # This hook is run after the action_controller railtie has set the configuration
- # based on the *environment* configuration and before any config/initializers are run
- # and also before eager_loading (if enabled).
- initializer 'active_model_serializers.set_configs', after: 'action_controller.set_configs' do
- ActiveModelSerializers.logger = Rails.configuration.action_controller.logger
- ActiveModelSerializers.config.perform_caching = Rails.configuration.action_controller.perform_caching
- # We want this hook to run after the config has been set, even if ActionController has already loaded.
- ActiveSupport.on_load(:action_controller) do
- ActiveModelSerializers.config.cache_store = ActionController::Base.cache_store
- end
- end
-
- # :nocov:
- generators do |app|
- Rails::Generators.configure!(app.config.generators)
- Rails::Generators.hidden_namespaces.uniq!
- require 'generators/rails/resource_override'
- end
- # :nocov:
-
- if Rails.env.test?
- ActionController::TestCase.send(:include, ActiveModelSerializers::Test::Schema)
- ActionController::TestCase.send(:include, ActiveModelSerializers::Test::Serializer)
- end
- end
-end
diff --git a/lib/active_model_serializers/register_jsonapi_renderer.rb b/lib/active_model_serializers/register_jsonapi_renderer.rb
deleted file mode 100644
index 715c6ab3..00000000
--- a/lib/active_model_serializers/register_jsonapi_renderer.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-# Based on discussion in https://github.com/rails/rails/pull/23712#issuecomment-184977238,
-# the JSON API media type will have its own format/renderer.
-#
-# > We recommend the media type be registered on its own as jsonapi
-# when a jsonapi Renderer and deserializer (Http::Parameters::DEFAULT_PARSERS) are added.
-#
-# Usage:
-#
-# ActiveSupport.on_load(:action_controller) do
-# require 'active_model_serializers/register_jsonapi_renderer'
-# end
-#
-# And then in controllers, use `render jsonapi: model` rather than `render json: model, adapter: :json_api`.
-#
-# For example, in a controller action, we can:
-# respond_to do |format|
-# format.jsonapi { render jsonapi: model }
-# end
-#
-# or
-#
-# render jsonapi: model
-#
-# No wrapper format needed as it does not apply (i.e. no `wrap_parameters format: [jsonapi]`)
-module ActiveModelSerializers
- module Jsonapi
- MEDIA_TYPE = 'application/vnd.api+json'.freeze
- HEADERS = {
- response: { 'CONTENT_TYPE'.freeze => MEDIA_TYPE },
- request: { 'ACCEPT'.freeze => MEDIA_TYPE }
- }.freeze
-
- def self.install
- # actionpack/lib/action_dispatch/http/mime_types.rb
- Mime::Type.register MEDIA_TYPE, :jsonapi
-
- if Rails::VERSION::MAJOR >= 5
- ActionDispatch::Request.parameter_parsers[:jsonapi] = parser
- else
- ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime[:jsonapi]] = parser
- end
-
- # ref https://github.com/rails/rails/pull/21496
- ActionController::Renderers.add :jsonapi do |json, options|
- json = serialize_jsonapi(json, options).to_json(options) unless json.is_a?(String)
- self.content_type ||= Mime[:jsonapi]
- self.response_body = json
- end
- end
-
- # Proposal: should actually deserialize the JSON API params
- # to the hash format expected by `ActiveModel::Serializers::JSON`
- # actionpack/lib/action_dispatch/http/parameters.rb
- def self.parser
- lambda do |body|
- data = JSON.parse(body)
- data = { _json: data } unless data.is_a?(Hash)
- data.with_indifferent_access
- end
- end
-
- module ControllerSupport
- def serialize_jsonapi(json, options)
- options[:adapter] = :json_api
- options.fetch(:serialization_context) do
- options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request)
- end
- get_serializer(json, options)
- end
- end
- end
-end
-
-ActiveModelSerializers::Jsonapi.install
-
-ActiveSupport.on_load(:action_controller) do
- include ActiveModelSerializers::Jsonapi::ControllerSupport
-end
diff --git a/lib/active_model_serializers/serializable_resource.rb b/lib/active_model_serializers/serializable_resource.rb
deleted file mode 100644
index f67cf238..00000000
--- a/lib/active_model_serializers/serializable_resource.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-require 'set'
-
-module ActiveModelSerializers
- class SerializableResource
- ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter, :meta, :meta_key, :links, :serialization_context, :key_transform])
- include ActiveModelSerializers::Logging
-
- delegate :serializable_hash, :as_json, :to_json, to: :adapter
- notify :serializable_hash, :render
- notify :as_json, :render
- notify :to_json, :render
-
- # Primary interface to composing a resource with a serializer and adapter.
- # @return the serializable_resource, ready for #as_json/#to_json/#serializable_hash.
- def initialize(resource, options = {})
- @resource = resource
- @adapter_opts, @serializer_opts =
- options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }.map { |h| Hash[h] }
- end
-
- def serialization_scope=(scope)
- serializer_opts[:scope] = scope
- end
-
- def serialization_scope
- serializer_opts[:scope]
- end
-
- def serialization_scope_name=(scope_name)
- serializer_opts[:scope_name] = scope_name
- end
-
- # NOTE: if no adapter is available, returns the resource itself. (i.e. adapter is a no-op)
- def adapter
- @adapter ||= find_adapter
- end
- alias adapter_instance adapter
-
- def find_adapter
- return resource unless serializer?
- adapter = catch :no_serializer do
- ActiveModelSerializers::Adapter.create(serializer_instance, adapter_opts)
- end
- adapter || resource
- end
-
- def serializer_instance
- @serializer_instance ||= serializer.new(resource, serializer_opts)
- end
-
- # Get serializer either explicitly :serializer or implicitly from resource
- # Remove :serializer key from serializer_opts
- # Remove :each_serializer if present and set as :serializer key
- def serializer
- @serializer ||=
- begin
- @serializer = serializer_opts.delete(:serializer)
- @serializer ||= ActiveModel::Serializer.serializer_for(resource, serializer_opts)
-
- if serializer_opts.key?(:each_serializer)
- serializer_opts[:serializer] = serializer_opts.delete(:each_serializer)
- end
- @serializer
- end
- end
- alias serializer_class serializer
-
- # True when no explicit adapter given, or explicit appear is truthy (non-nil)
- # False when explicit adapter is falsy (nil or false)
- def use_adapter?
- !(adapter_opts.key?(:adapter) && !adapter_opts[:adapter])
- end
-
- def serializer?
- use_adapter? && !serializer.nil?
- end
-
- protected
-
- attr_reader :resource, :adapter_opts, :serializer_opts
- end
-end
diff --git a/lib/active_model_serializers/serialization_context.rb b/lib/active_model_serializers/serialization_context.rb
deleted file mode 100644
index 9ef604f2..00000000
--- a/lib/active_model_serializers/serialization_context.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-require 'active_support/core_ext/array/extract_options'
-module ActiveModelSerializers
- class SerializationContext
- class << self
- attr_writer :url_helpers, :default_url_options
- def url_helpers
- @url_helpers ||= Module.new
- end
-
- def default_url_options
- @default_url_options ||= {}
- end
- end
- module UrlHelpers
- def self.included(base)
- base.send(:include, SerializationContext.url_helpers)
- end
-
- def default_url_options
- SerializationContext.default_url_options
- end
- end
-
- attr_reader :request_url, :query_parameters, :key_transform
-
- def initialize(*args)
- options = args.extract_options!
- if args.size == 1
- request = args.pop
- options[:request_url] = request.original_url[/\A[^?]+/]
- options[:query_parameters] = request.query_parameters
- end
- @request_url = options.delete(:request_url)
- @query_parameters = options.delete(:query_parameters)
- @url_helpers = options.delete(:url_helpers) || self.class.url_helpers
- @default_url_options = options.delete(:default_url_options) || self.class.default_url_options
- end
- end
-end
diff --git a/lib/active_model_serializers/test.rb b/lib/active_model_serializers/test.rb
deleted file mode 100644
index bec452ec..00000000
--- a/lib/active_model_serializers/test.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module ActiveModelSerializers
- module Test
- extend ActiveSupport::Autoload
- autoload :Serializer
- autoload :Schema
- end
-end
diff --git a/lib/active_model_serializers/test/schema.rb b/lib/active_model_serializers/test/schema.rb
deleted file mode 100644
index a0001586..00000000
--- a/lib/active_model_serializers/test/schema.rb
+++ /dev/null
@@ -1,138 +0,0 @@
-module ActiveModelSerializers
- module Test
- module Schema
- # A Minitest Assertion that test the response is valid against a schema.
- # @param schema_path [String] a custom schema path
- # @param message [String] a custom error message
- # @return [Boolean] true when the response is valid
- # @return [Minitest::Assertion] when the response is invalid
- # @example
- # get :index
- # assert_response_schema
- def assert_response_schema(schema_path = nil, message = nil)
- matcher = AssertResponseSchema.new(schema_path, request, response, message)
- assert(matcher.call, matcher.message)
- end
-
- def assert_request_schema(schema_path = nil, message = nil)
- matcher = AssertRequestSchema.new(schema_path, request, response, message)
- assert(matcher.call, matcher.message)
- end
-
- # May be renamed
- def assert_request_response_schema(schema_path = nil, message = nil)
- assert_request_schema(schema_path, message)
- assert_response_schema(schema_path, message)
- end
-
- def assert_schema(payload, schema_path = nil, message = nil)
- matcher = AssertSchema.new(schema_path, request, response, message, payload)
- assert(matcher.call, matcher.message)
- end
-
- MissingSchema = Class.new(Minitest::Assertion)
- InvalidSchemaError = Class.new(Minitest::Assertion)
-
- class AssertSchema
- attr_reader :schema_path, :request, :response, :message, :payload
-
- # Interface may change.
- def initialize(schema_path, request, response, message, payload = nil)
- require_json_schema!
- @request = request
- @response = response
- @payload = payload
- @schema_path = schema_path || schema_path_default
- @message = message
- @document_store = JsonSchema::DocumentStore.new
- add_schema_to_document_store
- end
-
- def call
- json_schema.expand_references!(store: document_store)
- status, errors = json_schema.validate(response_body)
- @message = [message, errors.map(&:to_s).to_sentence].compact.join(': ')
- status
- end
-
- protected
-
- attr_reader :document_store
-
- def controller_path
- request.filtered_parameters.with_indifferent_access[:controller]
- end
-
- def action
- request.filtered_parameters.with_indifferent_access[:action]
- end
-
- def schema_directory
- ActiveModelSerializers.config.schema_path
- end
-
- def schema_full_path
- "#{schema_directory}/#{schema_path}"
- end
-
- def schema_path_default
- "#{controller_path}/#{action}.json"
- end
-
- def schema_data
- load_json_file(schema_full_path)
- end
-
- def response_body
- load_json(response.body)
- end
-
- def request_params
- request.env['action_dispatch.request.request_parameters']
- end
-
- def json_schema
- @json_schema ||= JsonSchema.parse!(schema_data)
- end
-
- def add_schema_to_document_store
- Dir.glob("#{schema_directory}/**/*.json").each do |path|
- schema_data = load_json_file(path)
- extra_schema = JsonSchema.parse!(schema_data)
- document_store.add_schema(extra_schema)
- end
- end
-
- def load_json(json)
- JSON.parse(json)
- rescue JSON::ParserError => ex
- raise InvalidSchemaError, ex.message
- end
-
- def load_json_file(path)
- load_json(File.read(path))
- rescue Errno::ENOENT
- raise MissingSchema, "No Schema file at #{schema_full_path}"
- end
-
- def require_json_schema!
- require 'json_schema'
- rescue LoadError
- raise LoadError, "You don't have json_schema installed in your application. Please add it to your Gemfile and run bundle install"
- end
- end
- class AssertResponseSchema < AssertSchema
- def initialize(*)
- super
- @payload = response_body
- end
- end
- class AssertRequestSchema < AssertSchema
- def initialize(*)
- super
- @payload = request_params
- end
- end
- end
- end
-end
diff --git a/lib/active_model_serializers/test/serializer.rb b/lib/active_model_serializers/test/serializer.rb
deleted file mode 100644
index dc812c55..00000000
--- a/lib/active_model_serializers/test/serializer.rb
+++ /dev/null
@@ -1,125 +0,0 @@
-require 'set'
-module ActiveModelSerializers
- module Test
- module Serializer
- extend ActiveSupport::Concern
-
- included do
- setup :setup_serialization_subscriptions
- teardown :teardown_serialization_subscriptions
- end
-
- # Asserts that the request was rendered with the appropriate serializers.
- #
- # # assert that the "PostSerializer" serializer was rendered
- # assert_serializer "PostSerializer"
- #
- # # return a custom error message
- # assert_serializer "PostSerializer", "PostSerializer not rendered"
- #
- # # assert that the instance of PostSerializer was rendered
- # assert_serializer PostSerializer
- #
- # # assert that the "PostSerializer" serializer was rendered
- # assert_serializer :post_serializer
- #
- # # assert that the rendered serializer starts with "Post"
- # assert_serializer %r{\APost.+\Z}
- #
- # # assert that no serializer was rendered
- # assert_serializer nil
- #
- def assert_serializer(expectation, message = nil)
- @assert_serializer.expectation = expectation
- @assert_serializer.message = message
- @assert_serializer.response = response
- assert(@assert_serializer.matches?, @assert_serializer.message)
- end
-
- class AssertSerializer
- attr_reader :serializers, :message
- attr_accessor :response, :expectation
-
- def initialize
- @serializers = Set.new
- @_subscribers = []
- end
-
- def message=(message)
- @message = message || "expecting <#{expectation.inspect}> but rendering with <#{serializers.to_a}>"
- end
-
- def matches?
- # Force body to be read in case the template is being streamed.
- response.body
-
- case expectation
- when a_serializer? then matches_class?
- when Symbol then matches_symbol?
- when String then matches_string?
- when Regexp then matches_regexp?
- when NilClass then matches_nil?
- else fail ArgumentError, 'assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil'
- end
- end
-
- def subscribe
- @_subscribers << ActiveSupport::Notifications.subscribe(event_name) do |_name, _start, _finish, _id, payload|
- serializer = payload[:serializer].name
- serializers << serializer
- end
- end
-
- def unsubscribe
- @_subscribers.each do |subscriber|
- ActiveSupport::Notifications.unsubscribe(subscriber)
- end
- end
-
- private
-
- def matches_class?
- serializers.include?(expectation.name)
- end
-
- def matches_symbol?
- camelize_expectation = expectation.to_s.camelize
- serializers.include?(camelize_expectation)
- end
-
- def matches_string?
- !expectation.empty? && serializers.include?(expectation)
- end
-
- def matches_regexp?
- serializers.any? do |serializer|
- serializer.match(expectation)
- end
- end
-
- def matches_nil?
- serializers.empty?
- end
-
- def a_serializer?
- ->(exp) { exp.is_a?(Class) && exp < ActiveModel::Serializer }
- end
-
- def event_name
- ::ActiveModelSerializers::Logging::RENDER_EVENT
- end
- end
-
- private
-
- def setup_serialization_subscriptions
- @assert_serializer = AssertSerializer.new
- @assert_serializer.subscribe
- end
-
- def teardown_serialization_subscriptions
- @assert_serializer.unsubscribe
- end
- end
- end
-end
diff --git a/lib/generators/rails/USAGE b/lib/generators/rails/USAGE
deleted file mode 100644
index 85de6ad3..00000000
--- a/lib/generators/rails/USAGE
+++ /dev/null
@@ -1,6 +0,0 @@
-Description:
- Generates a serializer for the given resource.
-
-Example:
- `rails generate serializer Account name created_at`
-
diff --git a/lib/generators/rails/resource_override.rb b/lib/generators/rails/resource_override.rb
deleted file mode 100644
index 5177a636..00000000
--- a/lib/generators/rails/resource_override.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require 'rails/generators'
-require 'rails/generators/rails/resource/resource_generator'
-
-module Rails
- module Generators
- class ResourceGenerator
- hook_for :serializer, default: true, type: :boolean
- end
- end
-end
diff --git a/lib/generators/rails/serializer_generator.rb b/lib/generators/rails/serializer_generator.rb
deleted file mode 100644
index e670d5cf..00000000
--- a/lib/generators/rails/serializer_generator.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-module Rails
- module Generators
- class SerializerGenerator < NamedBase
- source_root File.expand_path('../templates', __FILE__)
- check_class_collision suffix: 'Serializer'
-
- argument :attributes, type: :array, default: [], banner: 'field:type field:type'
-
- class_option :parent, type: :string, desc: 'The parent class for the generated serializer'
-
- def create_serializer_file
- template 'serializer.rb.erb', File.join('app/serializers', class_path, "#{file_name}_serializer.rb")
- end
-
- private
-
- def attributes_names
- [:id] + attributes.reject(&:reference?).map! { |a| a.name.to_sym }
- end
-
- def association_names
- attributes.select(&:reference?).map! { |a| a.name.to_sym }
- end
-
- def parent_class_name
- if options[:parent]
- options[:parent]
- elsif 'ApplicationSerializer'.safe_constantize
- 'ApplicationSerializer'
- else
- 'ActiveModel::Serializer'
- end
- end
- end
- end
-end
diff --git a/lib/generators/rails/templates/serializer.rb.erb b/lib/generators/rails/templates/serializer.rb.erb
deleted file mode 100644
index 4ebb004e..00000000
--- a/lib/generators/rails/templates/serializer.rb.erb
+++ /dev/null
@@ -1,8 +0,0 @@
-<% module_namespacing do -%>
-class <%= class_name %>Serializer < <%= parent_class_name %>
- attributes <%= attributes_names.map(&:inspect).join(", ") %>
-<% association_names.each do |attribute| -%>
- has_one :<%= attribute %>
-<% end -%>
-end
-<% end -%>
diff --git a/lib/grape/active_model_serializers.rb b/lib/grape/active_model_serializers.rb
deleted file mode 100644
index 8dc7a314..00000000
--- a/lib/grape/active_model_serializers.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# To add Grape support, require 'grape/active_model_serializers' in the base of your Grape endpoints
-# Then add 'include Grape::ActiveModelSerializers' to enable the formatter and helpers
-require 'active_model_serializers'
-require 'grape/formatters/active_model_serializers'
-require 'grape/helpers/active_model_serializers'
-
-module Grape
- module ActiveModelSerializers
- extend ActiveSupport::Concern
-
- included do
- formatter :json, Grape::Formatters::ActiveModelSerializers
- helpers Grape::Helpers::ActiveModelSerializers
- end
- end
-end
diff --git a/lib/grape/formatters/active_model_serializers.rb b/lib/grape/formatters/active_model_serializers.rb
deleted file mode 100644
index 534c5bab..00000000
--- a/lib/grape/formatters/active_model_serializers.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# A Grape response formatter that can be used as 'formatter :json, Grape::Formatters::ActiveModelSerializers'
-#
-# Serializer options can be passed as a hash from your Grape endpoint using env[:active_model_serializer_options],
-# or better yet user the render helper in Grape::Helpers::ActiveModelSerializers
-
-require 'active_model_serializers/serialization_context'
-
-module Grape
- module Formatters
- module ActiveModelSerializers
- def self.call(resource, env)
- serializer_options = build_serializer_options(env)
- ::ActiveModelSerializers::SerializableResource.new(resource, serializer_options).to_json
- end
-
- def self.build_serializer_options(env)
- ams_options = env[:active_model_serializer_options] || {}
-
- # Add serialization context
- ams_options.fetch(:serialization_context) do
- request = env['grape.request']
- ams_options[:serialization_context] = ::ActiveModelSerializers::SerializationContext.new(
- request_url: request.url[/\A[^?]+/],
- query_parameters: request.params
- )
- end
-
- ams_options
- end
- end
- end
-end
diff --git a/lib/grape/helpers/active_model_serializers.rb b/lib/grape/helpers/active_model_serializers.rb
deleted file mode 100644
index afbdab85..00000000
--- a/lib/grape/helpers/active_model_serializers.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# Helpers can be included in your Grape endpoint as: helpers Grape::Helpers::ActiveModelSerializers
-
-module Grape
- module Helpers
- module ActiveModelSerializers
- # A convenience method for passing ActiveModelSerializers serializer options
- #
- # Example: To include relationships in the response: render(post, include: ['comments'])
- #
- # Example: To include pagination meta data: render(posts, meta: { page: posts.page, total_pages: posts.total_pages })
- def render(resource, active_model_serializer_options = {})
- env[:active_model_serializer_options] = active_model_serializer_options
- resource
- end
- end
- end
-end
diff --git a/lib/tasks/rubocop.rake b/lib/tasks/rubocop.rake
deleted file mode 100644
index 5c9a1242..00000000
--- a/lib/tasks/rubocop.rake
+++ /dev/null
@@ -1,53 +0,0 @@
-begin
- require 'rubocop'
- require 'rubocop/rake_task'
-rescue LoadError # rubocop:disable Lint/HandleExceptions
-else
- require 'rbconfig'
- # https://github.com/bundler/bundler/blob/1b3eb2465a/lib/bundler/constants.rb#L2
- windows_platforms = /(msdos|mswin|djgpp|mingw)/
- if RbConfig::CONFIG['host_os'] =~ windows_platforms
- desc 'No-op rubocop on Windows-- unsupported platform'
- task :rubocop do
- puts 'Skipping rubocop on Windows'
- end
- elsif defined?(::Rubinius)
- desc 'No-op rubocop to avoid rbx segfault'
- task :rubocop do
- puts 'Skipping rubocop on rbx due to segfault'
- puts 'https://github.com/rubinius/rubinius/issues/3499'
- end
- else
- Rake::Task[:rubocop].clear if Rake::Task.task_defined?(:rubocop)
- patterns = [
- 'Gemfile',
- 'Rakefile',
- 'lib/**/*.{rb,rake}',
- 'config/**/*.rb',
- 'app/**/*.rb',
- 'test/**/*.rb'
- ]
- desc 'Execute rubocop'
- RuboCop::RakeTask.new(:rubocop) do |task|
- task.options = ['--rails', '--display-cop-names', '--display-style-guide']
- task.formatters = ['progress']
- task.patterns = patterns
- task.fail_on_error = true
- end
-
- namespace :rubocop do
- desc 'Auto-gen rubocop config'
- task :auto_gen_config do
- options = ['--auto-gen-config'].concat patterns
- require 'benchmark'
- result = 0
- cli = RuboCop::CLI.new
- time = Benchmark.realtime do
- result = cli.run(options)
- end
- puts "Finished in #{time} seconds" if cli.options[:debug]
- abort('RuboCop failed!') if result.nonzero?
- end
- end
- end
-end
diff --git a/test/action_controller/adapter_selector_test.rb b/test/action_controller/adapter_selector_test.rb
deleted file mode 100644
index 3373de7c..00000000
--- a/test/action_controller/adapter_selector_test.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-require 'test_helper'
-
-module ActionController
- module Serialization
- class AdapterSelectorTest < ActionController::TestCase
- class Profile < Model
- attributes :id, :name, :description
- associations :comments
- end
- class ProfileSerializer < ActiveModel::Serializer
- type 'profiles'
- attributes :name, :description
- end
-
- class AdapterSelectorTestController < ActionController::Base
- def render_using_default_adapter
- @profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- render json: @profile
- end
-
- def render_using_adapter_override
- @profile = Profile.new(id: 'render_using_adapter_override', name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- render json: @profile, adapter: :json_api
- end
-
- def render_skipping_adapter
- @profile = Profile.new(id: 'render_skipping_adapter_id', name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- render json: @profile, adapter: false
- end
- end
-
- tests AdapterSelectorTestController
-
- def test_render_using_default_adapter
- get :render_using_default_adapter
- assert_equal '{"name":"Name 1","description":"Description 1"}', response.body
- end
-
- def test_render_using_adapter_override
- get :render_using_adapter_override
-
- expected = {
- data: {
- id: 'render_using_adapter_override',
- type: 'profiles',
- attributes: {
- name: 'Name 1',
- description: 'Description 1'
- }
- }
- }
-
- assert_equal expected.to_json, response.body
- end
-
- def test_render_skipping_adapter
- get :render_skipping_adapter
- assert_equal '{"id":"render_skipping_adapter_id","name":"Name 1","description":"Description 1"}', response.body
- end
- end
- end
-end
diff --git a/test/action_controller/explicit_serializer_test.rb b/test/action_controller/explicit_serializer_test.rb
deleted file mode 100644
index a23b6f6b..00000000
--- a/test/action_controller/explicit_serializer_test.rb
+++ /dev/null
@@ -1,135 +0,0 @@
-require 'test_helper'
-
-module ActionController
- module Serialization
- class ExplicitSerializerTest < ActionController::TestCase
- class ExplicitSerializerTestController < ActionController::Base
- def render_using_explicit_serializer
- @profile = Profile.new(name: 'Name 1',
- description: 'Description 1',
- comments: 'Comments 1')
- render json: @profile, serializer: ProfilePreviewSerializer
- end
-
- def render_array_using_explicit_serializer
- array = [
- Profile.new(name: 'Name 1',
- description: 'Description 1',
- comments: 'Comments 1'),
- Profile.new(name: 'Name 2',
- description: 'Description 2',
- comments: 'Comments 2')
- ]
- render json: array,
- serializer: PaginatedSerializer,
- each_serializer: ProfilePreviewSerializer
- end
-
- def render_array_using_implicit_serializer
- array = [
- Profile.new(name: 'Name 1',
- description: 'Description 1',
- comments: 'Comments 1'),
- Profile.new(name: 'Name 2',
- description: 'Description 2',
- comments: 'Comments 2')
- ]
- render json: array,
- each_serializer: ProfilePreviewSerializer
- end
-
- def render_array_using_explicit_serializer_and_custom_serializers
- @post = Post.new(title: 'New Post', body: 'Body')
- @author = Author.new(name: 'Jane Blogger')
- @author.posts = [@post]
- @post.author = @author
- @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
- @post.comments = [@first_comment, @second_comment]
- @first_comment.post = @post
- @first_comment.author = nil
- @second_comment.post = @post
- @second_comment.author = nil
- @blog = Blog.new(id: 23, name: 'AMS Blog')
- @post.blog = @blog
-
- render json: [@post], each_serializer: PostPreviewSerializer
- end
-
- def render_using_explicit_each_serializer
- location = Location.new(id: 42, lat: '-23.550520', lng: '-46.633309')
- place = Place.new(id: 1337, name: 'Amazing Place', locations: [location])
-
- render json: place, each_serializer: PlaceSerializer
- end
- end
-
- tests ExplicitSerializerTestController
-
- def test_render_using_explicit_serializer
- get :render_using_explicit_serializer
-
- assert_equal 'application/json', @response.content_type
- assert_equal '{"name":"Name 1"}', @response.body
- end
-
- def test_render_array_using_explicit_serializer
- get :render_array_using_explicit_serializer
- assert_equal 'application/json', @response.content_type
-
- expected = [
- { 'name' => 'Name 1' },
- { 'name' => 'Name 2' }
- ]
-
- assert_equal expected.to_json, @response.body
- end
-
- def test_render_array_using_implicit_serializer
- get :render_array_using_implicit_serializer
- assert_equal 'application/json', @response.content_type
-
- expected = [
- { 'name' => 'Name 1' },
- { 'name' => 'Name 2' }
- ]
- assert_equal expected.to_json, @response.body
- end
-
- def test_render_array_using_explicit_serializer_and_custom_serializers
- get :render_array_using_explicit_serializer_and_custom_serializers
-
- expected = [
- {
- 'title' => 'New Post',
- 'body' => 'Body',
- 'id' => @controller.instance_variable_get(:@post).id,
- 'comments' => [{ 'id' => 1 }, { 'id' => 2 }],
- 'author' => { 'id' => @controller.instance_variable_get(:@author).id }
- }
- ]
-
- assert_equal expected.to_json, @response.body
- end
-
- def test_render_using_explicit_each_serializer
- get :render_using_explicit_each_serializer
-
- expected = {
- id: 1337,
- name: 'Amazing Place',
- locations: [
- {
- id: 42,
- lat: '-23.550520',
- lng: '-46.633309',
- address: 'Nowhere' # is a virtual attribute on LocationSerializer
- }
- ]
- }
-
- assert_equal expected.to_json, response.body
- end
- end
- end
-end
diff --git a/test/action_controller/json/include_test.rb b/test/action_controller/json/include_test.rb
deleted file mode 100644
index 1fc8863e..00000000
--- a/test/action_controller/json/include_test.rb
+++ /dev/null
@@ -1,246 +0,0 @@
-require 'test_helper'
-
-module ActionController
- module Serialization
- class Json
- class IncludeTest < ActionController::TestCase
- INCLUDE_STRING = 'posts.comments'.freeze
- INCLUDE_HASH = { posts: :comments }.freeze
- DEEP_INCLUDE = 'posts.comments.author'.freeze
-
- class IncludeTestController < ActionController::Base
- def setup_data
- ActionController::Base.cache_store.clear
-
- @author = Author.new(id: 1, name: 'Steve K.')
-
- @post = Post.new(id: 42, title: 'New Post', body: 'Body')
- @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
-
- @post.comments = [@first_comment, @second_comment]
- @post.author = @author
-
- @first_comment.post = @post
- @second_comment.post = @post
-
- @blog = Blog.new(id: 1, name: 'My Blog!!')
- @post.blog = @blog
- @author.posts = [@post]
-
- @first_comment.author = @author
- @second_comment.author = @author
- @author.comments = [@first_comment, @second_comment]
- @author.roles = []
- @author.bio = {}
- end
-
- def render_without_include
- setup_data
- render json: @author, adapter: :json
- end
-
- def render_resource_with_include_hash
- setup_data
- render json: @author, include: INCLUDE_HASH, adapter: :json
- end
-
- def render_resource_with_include_string
- setup_data
- render json: @author, include: INCLUDE_STRING, adapter: :json
- end
-
- def render_resource_with_deep_include
- setup_data
- render json: @author, include: DEEP_INCLUDE, adapter: :json
- end
-
- def render_without_recursive_relationships
- # testing recursive includes ('**') can't have any cycles in the
- # relationships, or we enter an infinite loop.
- author = Author.new(id: 11, name: 'Jane Doe')
- post = Post.new(id: 12, title: 'Hello World', body: 'My first post')
- comment = Comment.new(id: 13, body: 'Commentary')
- author.posts = [post]
- post.comments = [comment]
- render json: author
- end
- end
-
- tests IncludeTestController
-
- def test_render_without_include
- get :render_without_include
- response = JSON.parse(@response.body)
- expected = {
- 'author' => {
- 'id' => 1,
- 'name' => 'Steve K.',
- 'posts' => [
- {
- 'id' => 42, 'title' => 'New Post', 'body' => 'Body'
- }
- ],
- 'roles' => [],
- 'bio' => {}
- }
- }
-
- assert_equal(expected, response)
- end
-
- def test_render_resource_with_include_hash
- get :render_resource_with_include_hash
- response = JSON.parse(@response.body)
-
- assert_equal(expected_include_response, response)
- end
-
- def test_render_resource_with_include_string
- get :render_resource_with_include_string
-
- response = JSON.parse(@response.body)
-
- assert_equal(expected_include_response, response)
- end
-
- def test_render_resource_with_deep_include
- get :render_resource_with_deep_include
-
- response = JSON.parse(@response.body)
-
- assert_equal(expected_deep_include_response, response)
- end
-
- def test_render_with_empty_default_includes
- with_default_includes '' do
- get :render_without_include
- response = JSON.parse(@response.body)
- expected = {
- 'author' => {
- 'id' => 1,
- 'name' => 'Steve K.'
- }
- }
- assert_equal(expected, response)
- end
- end
-
- def test_render_with_recursive_default_includes
- with_default_includes '**' do
- get :render_without_recursive_relationships
- response = JSON.parse(@response.body)
-
- expected = {
- 'id' => 11,
- 'name' => 'Jane Doe',
- 'roles' => nil,
- 'bio' => nil,
- 'posts' => [
- {
- 'id' => 12,
- 'title' => 'Hello World',
- 'body' => 'My first post',
- 'comments' => [
- {
- 'id' => 13,
- 'body' => 'Commentary',
- 'post' => nil, # not set to avoid infinite recursion
- 'author' => nil, # not set to avoid infinite recursion
- }
- ],
- 'blog' => {
- 'id' => 999,
- 'name' => 'Custom blog',
- 'writer' => nil,
- 'articles' => nil
- },
- 'author' => nil # not set to avoid infinite recursion
- }
- ]
- }
- assert_equal(expected, response)
- end
- end
-
- def test_render_with_includes_overrides_default_includes
- with_default_includes '' do
- get :render_resource_with_include_hash
- response = JSON.parse(@response.body)
-
- assert_equal(expected_include_response, response)
- end
- end
-
- private
-
- def expected_include_response
- {
- 'author' => {
- 'id' => 1,
- 'name' => 'Steve K.',
- 'posts' => [
- {
- 'id' => 42, 'title' => 'New Post', 'body' => 'Body',
- 'comments' => [
- {
- 'id' => 1, 'body' => 'ZOMG A COMMENT'
- },
- {
- 'id' => 2, 'body' => 'ZOMG ANOTHER COMMENT'
- }
- ]
- }
- ]
- }
- }
- end
-
- def expected_deep_include_response
- {
- 'author' => {
- 'id' => 1,
- 'name' => 'Steve K.',
- 'posts' => [
- {
- 'id' => 42, 'title' => 'New Post', 'body' => 'Body',
- 'comments' => [
- {
- 'id' => 1, 'body' => 'ZOMG A COMMENT',
- 'author' => {
- 'id' => 1,
- 'name' => 'Steve K.'
- }
- },
- {
- 'id' => 2, 'body' => 'ZOMG ANOTHER COMMENT',
- 'author' => {
- 'id' => 1,
- 'name' => 'Steve K.'
- }
- }
- ]
- }
- ]
- }
- }
- end
-
- def with_default_includes(include_directive)
- original = ActiveModelSerializers.config.default_includes
- ActiveModelSerializers.config.default_includes = include_directive
- clear_include_directive_cache
- yield
- ensure
- ActiveModelSerializers.config.default_includes = original
- clear_include_directive_cache
- end
-
- def clear_include_directive_cache
- ActiveModelSerializers
- .instance_variable_set(:@default_include_directive, nil)
- end
- end
- end
- end
-end
diff --git a/test/action_controller/json_api/deserialization_test.rb b/test/action_controller/json_api/deserialization_test.rb
deleted file mode 100644
index 025f857b..00000000
--- a/test/action_controller/json_api/deserialization_test.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-require 'test_helper'
-
-module ActionController
- module Serialization
- class JsonApi
- class DeserializationTest < ActionController::TestCase
- class DeserializationTestController < ActionController::Base
- def render_parsed_payload
- parsed_hash = ActiveModelSerializers::Deserialization.jsonapi_parse(params)
- render json: parsed_hash
- end
-
- def render_polymorphic_parsed_payload
- parsed_hash = ActiveModelSerializers::Deserialization.jsonapi_parse(
- params,
- polymorphic: [:restriction_for, :restricted_to]
- )
- render json: parsed_hash
- end
- end
-
- tests DeserializationTestController
-
- def test_deserialization_of_relationship_only_object
- hash = {
- 'data' => {
- 'type' => 'restraints',
- 'relationships' => {
- 'restriction_for' => {
- 'data' => {
- 'type' => 'discounts',
- 'id' => '67'
- }
- },
- 'restricted_to' => {
- 'data' => nil
- }
- }
- },
- 'restraint' => {}
- }
-
- post :render_polymorphic_parsed_payload, params: hash
-
- response = JSON.parse(@response.body)
- expected = {
- 'restriction_for_id' => '67',
- 'restriction_for_type' => 'discounts',
- 'restricted_to_id' => nil,
- 'restricted_to_type' => nil
- }
-
- assert_equal(expected, response)
- end
-
- def test_deserialization
- hash = {
- 'data' => {
- 'type' => 'photos',
- 'id' => 'zorglub',
- 'attributes' => {
- 'title' => 'Ember Hamster',
- 'src' => 'http://example.com/images/productivity.png',
- 'image-width' => '200',
- 'imageHeight' => '200',
- 'ImageSize' => '1024'
- },
- 'relationships' => {
- 'author' => {
- 'data' => nil
- },
- 'photographer' => {
- 'data' => { 'type' => 'people', 'id' => '9' }
- },
- 'comments' => {
- 'data' => [
- { 'type' => 'comments', 'id' => '1' },
- { 'type' => 'comments', 'id' => '2' }
- ]
- },
- 'related-images' => {
- 'data' => [
- { 'type' => 'image', 'id' => '7' },
- { 'type' => 'image', 'id' => '8' }
- ]
- }
- }
- }
- }
-
- post :render_parsed_payload, params: hash
-
- response = JSON.parse(@response.body)
- expected = {
- 'id' => 'zorglub',
- 'title' => 'Ember Hamster',
- 'src' => 'http://example.com/images/productivity.png',
- 'image_width' => '200',
- 'image_height' => '200',
- 'image_size' => '1024',
- 'author_id' => nil,
- 'photographer_id' => '9',
- 'comment_ids' => %w(1 2),
- 'related_image_ids' => %w(7 8)
- }
-
- assert_equal(expected, response)
- end
- end
- end
- end
-end
diff --git a/test/action_controller/json_api/errors_test.rb b/test/action_controller/json_api/errors_test.rb
deleted file mode 100644
index 6da3c9ad..00000000
--- a/test/action_controller/json_api/errors_test.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-require 'test_helper'
-
-module ActionController
- module Serialization
- class JsonApi
- class ErrorsTest < ActionController::TestCase
- def test_active_model_with_multiple_errors
- get :render_resource_with_errors
-
- expected_errors_object = {
- errors: [
- { source: { pointer: '/data/attributes/name' }, detail: 'cannot be nil' },
- { source: { pointer: '/data/attributes/name' }, detail: 'must be longer' },
- { source: { pointer: '/data/attributes/id' }, detail: 'must be a uuid' }
- ]
- }.to_json
- assert_equal json_response_body.to_json, expected_errors_object
- end
-
- def json_response_body
- JSON.load(@response.body)
- end
-
- class ErrorsTestController < ActionController::Base
- def render_resource_with_errors
- resource = Profile.new(name: 'Name 1',
- description: 'Description 1',
- comments: 'Comments 1')
- resource.errors.add(:name, 'cannot be nil')
- resource.errors.add(:name, 'must be longer')
- resource.errors.add(:id, 'must be a uuid')
- render json: resource, adapter: :json_api, serializer: ActiveModel::Serializer::ErrorSerializer
- end
- end
-
- tests ErrorsTestController
- end
- end
- end
-end
diff --git a/test/action_controller/json_api/fields_test.rb b/test/action_controller/json_api/fields_test.rb
deleted file mode 100644
index af87ad39..00000000
--- a/test/action_controller/json_api/fields_test.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-require 'test_helper'
-
-module ActionController
- module Serialization
- class JsonApi
- class FieldsTest < ActionController::TestCase
- class FieldsTestController < ActionController::Base
- class AuthorWithName < Author
- attributes :first_name, :last_name
- end
- class AuthorWithNameSerializer < AuthorSerializer
- type 'authors'
- end
- class PostWithPublishAt < Post
- attributes :publish_at
- end
- class PostWithPublishAtSerializer < ActiveModel::Serializer
- type 'posts'
- attributes :title, :body, :publish_at
- belongs_to :author
- has_many :comments
- end
-
- def setup_post
- ActionController::Base.cache_store.clear
- @author = AuthorWithName.new(id: 1, first_name: 'Bob', last_name: 'Jones')
- @comment1 = Comment.new(id: 7, body: 'cool', author: @author)
- @comment2 = Comment.new(id: 12, body: 'awesome', author: @author)
- @post = PostWithPublishAt.new(id: 1337, title: 'Title 1', body: 'Body 1',
- author: @author, comments: [@comment1, @comment2],
- publish_at: '2020-03-16T03:55:25.291Z')
- @comment1.post = @post
- @comment2.post = @post
- end
-
- def render_fields_works_on_relationships
- setup_post
- render json: @post, serializer: PostWithPublishAtSerializer, adapter: :json_api, fields: { posts: [:author] }
- end
- end
-
- tests FieldsTestController
-
- test 'fields works on relationships' do
- get :render_fields_works_on_relationships
- response = JSON.parse(@response.body)
- expected = {
- 'data' => {
- 'id' => '1337',
- 'type' => 'posts',
- 'relationships' => {
- 'author' => {
- 'data' => {
- 'id' => '1',
- 'type' => 'authors'
- }
- }
- }
- }
- }
- assert_equal expected, response
- end
- end
- end
- end
-end
diff --git a/test/action_controller/json_api/linked_test.rb b/test/action_controller/json_api/linked_test.rb
deleted file mode 100644
index 12019768..00000000
--- a/test/action_controller/json_api/linked_test.rb
+++ /dev/null
@@ -1,202 +0,0 @@
-require 'test_helper'
-
-module ActionController
- module Serialization
- class JsonApi
- class LinkedTest < ActionDispatch::IntegrationTest
- class LinkedTestController < ActionController::Base
- def setup_post
- ActionController::Base.cache_store.clear
- @role1 = Role.new(id: 1, name: 'admin')
- @role2 = Role.new(id: 2, name: 'colab')
- @author = Author.new(id: 1, name: 'Steve K.')
- @author.posts = []
- @author.bio = nil
- @author.roles = [@role1, @role2]
- @role1.author = @author
- @role2.author = @author
- @author2 = Author.new(id: 2, name: 'Anonymous')
- @author2.posts = []
- @author2.bio = nil
- @author2.roles = []
- @post = Post.new(id: 1, title: 'New Post', body: 'Body')
- @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
- @post.comments = [@first_comment, @second_comment]
- @post.author = @author
- @first_comment.post = @post
- @first_comment.author = @author2
- @second_comment.post = @post
- @second_comment.author = nil
- @post2 = Post.new(id: 2, title: 'Another Post', body: 'Body')
- @post2.author = @author
- @post2.comments = []
- @blog = Blog.new(id: 1, name: 'My Blog!!')
- @post.blog = @blog
- @post2.blog = @blog
- end
-
- def render_resource_without_include
- setup_post
- render json: @post
- end
-
- def render_resource_with_include
- setup_post
- render json: @post, adapter: :json_api, include: [:author]
- end
-
- def render_resource_with_include_of_custom_key_by_original
- setup_post
- render json: @post, adapter: :json_api, include: [:reviews], serializer: PostWithCustomKeysSerializer
- end
-
- def render_resource_with_nested_include
- setup_post
- render json: @post, adapter: :json_api, include: [comments: [:author]]
- end
-
- def render_resource_with_nested_has_many_include_wildcard
- setup_post
- render json: @post, adapter: :json_api, include: 'author.*'
- end
-
- def render_resource_with_missing_nested_has_many_include
- setup_post
- @post.author = @author2 # author2 has no roles.
- render json: @post, adapter: :json_api, include: [author: [:roles]]
- end
-
- def render_collection_with_missing_nested_has_many_include
- setup_post
- @post.author = @author2
- render json: [@post, @post2], adapter: :json_api, include: [author: [:roles]]
- end
-
- def render_collection_without_include
- setup_post
- render json: [@post], adapter: :json_api
- end
-
- def render_collection_with_include
- setup_post
- render json: [@post], adapter: :json_api, include: 'author, comments'
- end
- end
-
- setup do
- @routes = Rails.application.routes.draw do
- ActiveSupport::Deprecation.silence do
- match ':action', to: LinkedTestController, via: [:get, :post]
- end
- end
- end
-
- def test_render_resource_without_include
- get '/render_resource_without_include'
- response = JSON.parse(@response.body)
- refute response.key? 'included'
- end
-
- def test_render_resource_with_include
- get '/render_resource_with_include'
- response = JSON.parse(@response.body)
- assert response.key? 'included'
- assert_equal 1, response['included'].size
- assert_equal 'Steve K.', response['included'].first['attributes']['name']
- end
-
- def test_render_resource_with_nested_has_many_include
- get '/render_resource_with_nested_has_many_include_wildcard'
- response = JSON.parse(@response.body)
- expected_linked = [
- {
- 'id' => '1',
- 'type' => 'authors',
- 'attributes' => {
- 'name' => 'Steve K.'
- },
- 'relationships' => {
- 'posts' => { 'data' => [] },
- 'roles' => { 'data' => [{ 'type' => 'roles', 'id' => '1' }, { 'type' => 'roles', 'id' => '2' }] },
- 'bio' => { 'data' => nil }
- }
- }, {
- 'id' => '1',
- 'type' => 'roles',
- 'attributes' => {
- 'name' => 'admin',
- 'description' => nil,
- 'slug' => 'admin-1'
- },
- 'relationships' => {
- 'author' => { 'data' => { 'type' => 'authors', 'id' => '1' } }
- }
- }, {
- 'id' => '2',
- 'type' => 'roles',
- 'attributes' => {
- 'name' => 'colab',
- 'description' => nil,
- 'slug' => 'colab-2'
- },
- 'relationships' => {
- 'author' => { 'data' => { 'type' => 'authors', 'id' => '1' } }
- }
- }
- ]
- assert_equal expected_linked, response['included']
- end
-
- def test_render_resource_with_include_of_custom_key_by_original
- get '/render_resource_with_include_of_custom_key_by_original'
- response = JSON.parse(@response.body)
- assert response.key? 'included'
-
- relationships = response['data']['relationships']
-
- assert_includes relationships, 'reviews'
- assert_includes relationships, 'writer'
- assert_includes relationships, 'site'
- end
-
- def test_render_resource_with_nested_include
- get '/render_resource_with_nested_include'
- response = JSON.parse(@response.body)
- assert response.key? 'included'
- assert_equal 3, response['included'].size
- end
-
- def test_render_collection_without_include
- get '/render_collection_without_include'
- response = JSON.parse(@response.body)
- refute response.key? 'included'
- end
-
- def test_render_collection_with_include
- get '/render_collection_with_include'
- response = JSON.parse(@response.body)
- assert response.key? 'included'
- end
-
- def test_render_resource_with_nested_attributes_even_when_missing_associations
- get '/render_resource_with_missing_nested_has_many_include'
- response = JSON.parse(@response.body)
- assert response.key? 'included'
- refute include_type?(response['included'], 'roles')
- end
-
- def test_render_collection_with_missing_nested_has_many_include
- get '/render_collection_with_missing_nested_has_many_include'
- response = JSON.parse(@response.body)
- assert response.key? 'included'
- assert include_type?(response['included'], 'roles')
- end
-
- def include_type?(collection, value)
- collection.detect { |i| i['type'] == value }
- end
- end
- end
- end
-end
diff --git a/test/action_controller/json_api/pagination_test.rb b/test/action_controller/json_api/pagination_test.rb
deleted file mode 100644
index 0af086b7..00000000
--- a/test/action_controller/json_api/pagination_test.rb
+++ /dev/null
@@ -1,116 +0,0 @@
-require 'test_helper'
-require 'will_paginate/array'
-require 'kaminari'
-require 'kaminari/hooks'
-::Kaminari::Hooks.init
-
-module ActionController
- module Serialization
- class JsonApi
- class PaginationTest < ActionController::TestCase
- KAMINARI_URI = 'http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_kaminari'.freeze
- WILL_PAGINATE_URI = 'http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_will_paginate'.freeze
-
- class PaginationTestController < ActionController::Base
- def setup
- @array = [
- Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
- Profile.new(name: 'Name 2', description: 'Description 2', comments: 'Comments 2'),
- Profile.new(name: 'Name 3', description: 'Description 3', comments: 'Comments 3')
- ]
- end
-
- def using_kaminari
- setup
- Kaminari.paginate_array(@array).page(params[:page][:number]).per(params[:page][:size])
- end
-
- def using_will_paginate
- setup
- @array.paginate(page: params[:page][:number], per_page: params[:page][:size])
- end
-
- def render_pagination_using_kaminari
- render json: using_kaminari, adapter: :json_api
- end
-
- def render_pagination_using_will_paginate
- render json: using_will_paginate, adapter: :json_api
- end
-
- def render_array_without_pagination_links
- setup
- render json: @array, adapter: :json_api
- end
- end
-
- tests PaginationTestController
-
- def test_render_pagination_links_with_will_paginate
- expected_links = { 'self' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=1",
- 'first' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1",
- 'prev' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1",
- 'next' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1",
- 'last' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1" }
-
- get :render_pagination_using_will_paginate, params: { page: { number: 2, size: 1 } }
- response = JSON.parse(@response.body)
- assert_equal expected_links, response['links']
- end
-
- def test_render_only_last_and_next_pagination_links
- expected_links = { 'self' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2",
- 'next' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2",
- 'last' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2" }
- get :render_pagination_using_will_paginate, params: { page: { number: 1, size: 2 } }
- response = JSON.parse(@response.body)
- assert_equal expected_links, response['links']
- end
-
- def test_render_pagination_links_with_kaminari
- expected_links = { 'self' => "#{KAMINARI_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=1",
- 'first' => "#{KAMINARI_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1",
- 'prev' => "#{KAMINARI_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1",
- 'next' => "#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1",
- 'last' => "#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1" }
- get :render_pagination_using_kaminari, params: { page: { number: 2, size: 1 } }
- response = JSON.parse(@response.body)
- assert_equal expected_links, response['links']
- end
-
- def test_render_only_prev_and_first_pagination_links
- expected_links = { 'self' => "#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1",
- 'first' => "#{KAMINARI_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1",
- 'prev' => "#{KAMINARI_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=1" }
- get :render_pagination_using_kaminari, params: { page: { number: 3, size: 1 } }
- response = JSON.parse(@response.body)
- assert_equal expected_links, response['links']
- end
-
- def test_render_only_last_and_next_pagination_links_with_additional_params
- expected_links = { 'self' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2&teste=additional",
- 'next' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2&teste=additional",
- 'last' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2&teste=additional" }
- get :render_pagination_using_will_paginate, params: { page: { number: 1, size: 2 }, teste: 'additional' }
- response = JSON.parse(@response.body)
- assert_equal expected_links, response['links']
- end
-
- def test_render_only_prev_and_first_pagination_links_with_additional_params
- expected_links = { 'self' => "#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1&teste=additional",
- 'first' => "#{KAMINARI_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1&teste=additional",
- 'prev' => "#{KAMINARI_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=1&teste=additional" }
- get :render_pagination_using_kaminari, params: { page: { number: 3, size: 1 }, teste: 'additional' }
- response = JSON.parse(@response.body)
- assert_equal expected_links, response['links']
- end
-
- def test_array_without_pagination_links
- get :render_array_without_pagination_links, params: { page: { number: 2, size: 1 } }
- response = JSON.parse(@response.body)
- refute response.key? 'links'
- end
- end
- end
- end
-end
diff --git a/test/action_controller/json_api/transform_test.rb b/test/action_controller/json_api/transform_test.rb
deleted file mode 100644
index 69212f32..00000000
--- a/test/action_controller/json_api/transform_test.rb
+++ /dev/null
@@ -1,189 +0,0 @@
-require 'test_helper'
-
-module ActionController
- module Serialization
- class JsonApi
- class KeyTransformTest < ActionController::TestCase
- class KeyTransformTestController < ActionController::Base
- class Post < ::Model
- attributes :title, :body, :publish_at
- associations :author, :top_comments
- end
- class Author < ::Model
- attributes :first_name, :last_name
- end
- class TopComment < ::Model
- attributes :body
- associations :author, :post
- end
- class PostSerializer < ActiveModel::Serializer
- type 'posts'
- attributes :title, :body, :publish_at
- belongs_to :author
- has_many :top_comments
-
- link(:post_authors) { 'https://example.com/post_authors' }
-
- meta do
- {
- rating: 5,
- favorite_count: 10
- }
- end
- end
-
- class AuthorSerializer < ActiveModel::Serializer
- type 'authors'
- attributes :first_name, :last_name
- end
-
- class TopCommentSerializer < ActiveModel::Serializer
- type 'top_comments'
- attributes :body
- belongs_to :author
- end
-
- def setup_post
- ActionController::Base.cache_store.clear
- @author = Author.new(id: 1, first_name: 'Bob', last_name: 'Jones')
- @comment1 = TopComment.new(id: 7, body: 'cool', author: @author)
- @comment2 = TopComment.new(id: 12, body: 'awesome', author: @author)
- @post = Post.new(id: 1337, title: 'Title 1', body: 'Body 1',
- author: @author, top_comments: [@comment1, @comment2],
- publish_at: '2020-03-16T03:55:25.291Z')
- @comment1.post = @post
- @comment2.post = @post
- end
-
- def render_resource_with_transform
- setup_post
- render json: @post, serializer: PostSerializer, adapter: :json_api,
- key_transform: :camel
- end
-
- def render_resource_with_transform_nil
- setup_post
- render json: @post, serializer: PostSerializer, adapter: :json_api,
- key_transform: nil
- end
-
- def render_resource_with_transform_with_global_config
- old_transform = ActiveModelSerializers.config.key_transform
- setup_post
- ActiveModelSerializers.config.key_transform = :camel_lower
- render json: @post, serializer: PostSerializer, adapter: :json_api
- ensure
- ActiveModelSerializers.config.key_transform = old_transform
- end
- end
-
- tests KeyTransformTestController
-
- def test_render_resource_with_transform
- get :render_resource_with_transform
- response = JSON.parse(@response.body)
- expected = {
- 'Data' => {
- 'Id' => '1337',
- 'Type' => 'Posts',
- 'Attributes' => {
- 'Title' => 'Title 1',
- 'Body' => 'Body 1',
- 'PublishAt' => '2020-03-16T03:55:25.291Z'
- },
- 'Relationships' => {
- 'Author' => {
- 'Data' => {
- 'Id' => '1',
- 'Type' => 'Authors'
- }
- },
- 'TopComments' => {
- 'Data' => [
- { 'Id' => '7', 'Type' => 'TopComments' },
- { 'Id' => '12', 'Type' => 'TopComments' }
- ]
- }
- },
- 'Links' => {
- 'PostAuthors' => 'https://example.com/post_authors'
- },
- 'Meta' => { 'Rating' => 5, 'FavoriteCount' => 10 }
- }
- }
- assert_equal expected, response
- end
-
- def test_render_resource_with_transform_nil
- get :render_resource_with_transform_nil
- response = JSON.parse(@response.body)
- expected = {
- 'data' => {
- 'id' => '1337',
- 'type' => 'posts',
- 'attributes' => {
- 'title' => 'Title 1',
- 'body' => 'Body 1',
- 'publish-at' => '2020-03-16T03:55:25.291Z'
- },
- 'relationships' => {
- 'author' => {
- 'data' => {
- 'id' => '1',
- 'type' => 'authors'
- }
- },
- 'top-comments' => {
- 'data' => [
- { 'id' => '7', 'type' => 'top-comments' },
- { 'id' => '12', 'type' => 'top-comments' }
- ]
- }
- },
- 'links' => {
- 'post-authors' => 'https://example.com/post_authors'
- },
- 'meta' => { 'rating' => 5, 'favorite-count' => 10 }
- }
- }
- assert_equal expected, response
- end
-
- def test_render_resource_with_transform_with_global_config
- get :render_resource_with_transform_with_global_config
- response = JSON.parse(@response.body)
- expected = {
- 'data' => {
- 'id' => '1337',
- 'type' => 'posts',
- 'attributes' => {
- 'title' => 'Title 1',
- 'body' => 'Body 1',
- 'publishAt' => '2020-03-16T03:55:25.291Z'
- },
- 'relationships' => {
- 'author' => {
- 'data' => {
- 'id' => '1',
- 'type' => 'authors'
- }
- },
- 'topComments' => {
- 'data' => [
- { 'id' => '7', 'type' => 'topComments' },
- { 'id' => '12', 'type' => 'topComments' }
- ]
- }
- },
- 'links' => {
- 'postAuthors' => 'https://example.com/post_authors'
- },
- 'meta' => { 'rating' => 5, 'favoriteCount' => 10 }
- }
- }
- assert_equal expected, response
- end
- end
- end
- end
-end
diff --git a/test/action_controller/lookup_proc_test.rb b/test/action_controller/lookup_proc_test.rb
deleted file mode 100644
index 4d2ad0b1..00000000
--- a/test/action_controller/lookup_proc_test.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'test_helper'
-
-module ActionController
- module Serialization
- class LookupProcTest < ActionController::TestCase
- module Api
- module V3
- class PostCustomSerializer < ActiveModel::Serializer
- attributes :title, :body
-
- belongs_to :author
- end
-
- class AuthorCustomSerializer < ActiveModel::Serializer
- attributes :name
- end
-
- class LookupProcTestController < ActionController::Base
- def implicit_namespaced_serializer
- author = Author.new(name: 'Bob')
- post = Post.new(title: 'New Post', body: 'Body', author: author)
-
- render json: post
- end
- end
- end
- end
-
- tests Api::V3::LookupProcTestController
-
- test 'implicitly uses namespaced serializer' do
- controller_namespace = lambda do |resource_class, _parent_serializer_class, namespace|
- "#{namespace}::#{resource_class}CustomSerializer" if namespace
- end
-
- with_prepended_lookup(controller_namespace) do
- get :implicit_namespaced_serializer
-
- assert_serializer Api::V3::PostCustomSerializer
-
- expected = { 'title' => 'New Post', 'body' => 'Body', 'author' => { 'name' => 'Bob' } }
- actual = JSON.parse(@response.body)
-
- assert_equal expected, actual
- end
- end
- end
- end
-end
diff --git a/test/action_controller/namespace_lookup_test.rb b/test/action_controller/namespace_lookup_test.rb
deleted file mode 100644
index b5c8f496..00000000
--- a/test/action_controller/namespace_lookup_test.rb
+++ /dev/null
@@ -1,232 +0,0 @@
-require 'test_helper'
-
-module ActionController
- module Serialization
- class NamespaceLookupTest < ActionController::TestCase
- class Book < ::Model
- attributes :id, :title, :body
- associations :writer, :chapters
- end
- class Chapter < ::Model
- attributes :title
- end
- class Writer < ::Model
- attributes :name
- end
-
- module Api
- module V2
- class BookSerializer < ActiveModel::Serializer
- attributes :title
- end
- end
-
- module VHeader
- class BookSerializer < ActiveModel::Serializer
- attributes :title, :body
-
- def body
- 'header'
- end
- end
- end
-
- module V3
- class BookSerializer < ActiveModel::Serializer
- attributes :title, :body
-
- belongs_to :writer
- has_many :chapters
- end
-
- class ChapterSerializer < ActiveModel::Serializer
- attribute :title do
- "Chapter - #{object.title}"
- end
- end
-
- class WriterSerializer < ActiveModel::Serializer
- attributes :name
- end
-
- class LookupTestController < ActionController::Base
- before_action only: [:namespace_set_in_before_filter] do
- self.namespace_for_serializer = Api::V2
- end
-
- def implicit_namespaced_serializer
- writer = Writer.new(name: 'Bob')
- book = Book.new(title: 'New Post', body: 'Body', writer: writer, chapters: [])
-
- render json: book
- end
-
- def implicit_namespaced_collection_serializer
- chapter1 = Chapter.new(title: 'Oh')
- chapter2 = Chapter.new(title: 'Oh my')
-
- render json: [chapter1, chapter2]
- end
-
- def implicit_has_many_namespaced_serializer
- chapter1 = Chapter.new(title: 'Odd World')
- chapter2 = Chapter.new(title: 'New World')
- book = Book.new(title: 'New Post', body: 'Body', chapters: [chapter1, chapter2])
-
- render json: book
- end
-
- def explicit_namespace_as_module
- book = Book.new(title: 'New Post', body: 'Body')
-
- render json: book, namespace: Api::V2
- end
-
- def explicit_namespace_as_string
- book = Book.new(title: 'New Post', body: 'Body')
-
- # because this is a string, ruby can't auto-lookup the constant, so otherwise
- # the lookup thinks we mean ::Api::V2
- render json: book, namespace: 'ActionController::Serialization::NamespaceLookupTest::Api::V2'
- end
-
- def explicit_namespace_as_symbol
- book = Book.new(title: 'New Post', body: 'Body')
-
- # because this is a string, ruby can't auto-lookup the constant, so otherwise
- # the lookup thinks we mean ::Api::V2
- render json: book, namespace: :'ActionController::Serialization::NamespaceLookupTest::Api::V2'
- end
-
- def invalid_namespace
- book = Book.new(id: 'invalid_namespace_book_id', title: 'New Post', body: 'Body')
-
- render json: book, namespace: :api_v2
- end
-
- def namespace_set_in_before_filter
- book = Book.new(title: 'New Post', body: 'Body')
- render json: book
- end
-
- def namespace_set_by_request_headers
- book = Book.new(title: 'New Post', body: 'Body')
- version_from_header = request.headers['X-API_VERSION']
- namespace = "ActionController::Serialization::NamespaceLookupTest::#{version_from_header}"
-
- render json: book, namespace: namespace
- end
- end
- end
- end
-
- tests Api::V3::LookupTestController
-
- setup do
- @test_namespace = self.class.parent
- end
-
- test 'uses request headers to determine the namespace' do
- request.env['X-API_VERSION'] = 'Api::VHeader'
- get :namespace_set_by_request_headers
-
- assert_serializer Api::VHeader::BookSerializer
- end
-
- test 'implicitly uses namespaced serializer' do
- get :implicit_namespaced_serializer
-
- assert_serializer Api::V3::BookSerializer
-
- expected = { 'title' => 'New Post', 'body' => 'Body', 'writer' => { 'name' => 'Bob' }, 'chapters' => [] }
- actual = JSON.parse(@response.body)
-
- assert_equal expected, actual
- end
-
- test 'implicitly uses namespaced serializer for collection' do
- get :implicit_namespaced_collection_serializer
-
- assert_serializer 'ActiveModel::Serializer::CollectionSerializer'
-
- expected = [{ 'title' => 'Chapter - Oh' }, { 'title' => 'Chapter - Oh my' }]
- actual = JSON.parse(@response.body)
-
- assert_equal expected, actual
- end
-
- test 'implicitly uses namespaced serializer for has_many' do
- get :implicit_has_many_namespaced_serializer
-
- assert_serializer Api::V3::BookSerializer
-
- expected = {
- 'title' => 'New Post',
- 'body' => 'Body', 'writer' => nil,
- 'chapters' => [
- { 'title' => 'Chapter - Odd World' },
- { 'title' => 'Chapter - New World' }
- ]
- }
- actual = JSON.parse(@response.body)
-
- assert_equal expected, actual
- end
-
- test 'explicit namespace as module' do
- get :explicit_namespace_as_module
-
- assert_serializer Api::V2::BookSerializer
-
- expected = { 'title' => 'New Post' }
- actual = JSON.parse(@response.body)
-
- assert_equal expected, actual
- end
-
- test 'explicit namespace as string' do
- get :explicit_namespace_as_string
-
- assert_serializer Api::V2::BookSerializer
-
- expected = { 'title' => 'New Post' }
- actual = JSON.parse(@response.body)
-
- assert_equal expected, actual
- end
-
- test 'explicit namespace as symbol' do
- get :explicit_namespace_as_symbol
-
- assert_serializer Api::V2::BookSerializer
-
- expected = { 'title' => 'New Post' }
- actual = JSON.parse(@response.body)
-
- assert_equal expected, actual
- end
-
- test 'invalid namespace' do
- get :invalid_namespace
-
- assert_serializer ActiveModel::Serializer::Null
-
- expected = { 'id' => 'invalid_namespace_book_id', 'title' => 'New Post', 'body' => 'Body' }
- actual = JSON.parse(@response.body)
-
- assert_equal expected, actual
- end
-
- test 'namespace set in before filter' do
- get :namespace_set_in_before_filter
-
- assert_serializer Api::V2::BookSerializer
-
- expected = { 'title' => 'New Post' }
- actual = JSON.parse(@response.body)
-
- assert_equal expected, actual
- end
- end
- end
-end
diff --git a/test/action_controller/serialization_scope_name_test.rb b/test/action_controller/serialization_scope_name_test.rb
deleted file mode 100644
index 3d767d04..00000000
--- a/test/action_controller/serialization_scope_name_test.rb
+++ /dev/null
@@ -1,235 +0,0 @@
-require 'test_helper'
-
-module SerializationScopeTesting
- class User < ActiveModelSerializers::Model
- attributes :id, :name, :admin
- def admin?
- admin
- end
- end
- class Comment < ActiveModelSerializers::Model
- attributes :id, :body
- end
- class Post < ActiveModelSerializers::Model
- attributes :id, :title, :body, :comments
- end
- class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body, :comments
-
- def body
- "The 'scope' is the 'current_user': #{scope == current_user}"
- end
-
- def comments
- if current_user.admin?
- [Comment.new(id: 1, body: 'Admin')]
- else
- [Comment.new(id: 2, body: 'Scoped')]
- end
- end
-
- def json_key
- 'post'
- end
- end
- class PostTestController < ActionController::Base
- attr_writer :current_user
-
- def render_post_by_non_admin
- self.current_user = User.new(id: 3, name: 'Pete', admin: false)
- render json: new_post, serializer: serializer, adapter: :json
- end
-
- def render_post_by_admin
- self.current_user = User.new(id: 3, name: 'Pete', admin: true)
- render json: new_post, serializer: serializer, adapter: :json
- end
-
- def current_user
- defined?(@current_user) ? @current_user : :current_user_not_set
- end
-
- private
-
- def new_post
- Post.new(id: 4, title: 'Title')
- end
-
- def serializer
- PostSerializer
- end
- end
- class PostViewContextSerializer < PostSerializer
- def body
- "The 'scope' is the 'view_context': #{scope == view_context}"
- end
-
- def comments
- if view_context.controller.current_user.admin?
- [Comment.new(id: 1, body: 'Admin')]
- else
- [Comment.new(id: 2, body: 'Scoped')]
- end
- end
- end
- class DefaultScopeTest < ActionController::TestCase
- tests PostTestController
-
- def test_default_serialization_scope
- assert_equal :current_user, @controller._serialization_scope
- end
-
- def test_default_serialization_scope_object
- assert_equal :current_user_not_set, @controller.current_user
- assert_equal :current_user_not_set, @controller.serialization_scope
- end
-
- def test_default_scope_non_admin
- get :render_post_by_non_admin
- expected_json = {
- post: {
- id: 4,
- title: 'Title',
- body: "The 'scope' is the 'current_user': true",
- comments: [
- { id: 2, body: 'Scoped' }
- ]
- }
- }.to_json
- assert_equal expected_json, @response.body
- end
-
- def test_default_scope_admin
- get :render_post_by_admin
- expected_json = {
- post: {
- id: 4,
- title: 'Title',
- body: "The 'scope' is the 'current_user': true",
- comments: [
- { id: 1, body: 'Admin' }
- ]
- }
- }.to_json
- assert_equal expected_json, @response.body
- end
- end
- class SerializationScopeTest < ActionController::TestCase
- class PostViewContextTestController < PostTestController
- serialization_scope :view_context
-
- private
-
- def serializer
- PostViewContextSerializer
- end
- end
- tests PostViewContextTestController
-
- def test_defined_serialization_scope
- assert_equal :view_context, @controller._serialization_scope
- end
-
- def test_defined_serialization_scope_object
- assert_equal @controller.view_context.controller, @controller.serialization_scope.controller
- end
-
- def test_serialization_scope_non_admin
- get :render_post_by_non_admin
- expected_json = {
- post: {
- id: 4,
- title: 'Title',
- body: "The 'scope' is the 'view_context': true",
- comments: [
- { id: 2, body: 'Scoped' }
- ]
- }
- }.to_json
- assert_equal expected_json, @response.body
- end
-
- def test_serialization_scope_admin
- get :render_post_by_admin
- expected_json = {
- post: {
- id: 4,
- title: 'Title',
- body: "The 'scope' is the 'view_context': true",
- comments: [
- { id: 1, body: 'Admin' }
- ]
- }
- }.to_json
- assert_equal expected_json, @response.body
- end
- end
- class NilSerializationScopeTest < ActionController::TestCase
- class PostViewContextTestController < ActionController::Base
- serialization_scope nil
-
- attr_accessor :current_user
-
- def render_post_with_no_scope
- self.current_user = User.new(id: 3, name: 'Pete', admin: false)
- render json: new_post, serializer: PostSerializer, adapter: :json
- end
-
- def render_post_with_passed_in_scope
- self.current_user = User.new(id: 3, name: 'Pete', admin: false)
- render json: new_post, serializer: PostSerializer, adapter: :json, scope: current_user, scope_name: :current_user
- end
-
- def render_post_with_passed_in_scope_without_scope_name
- self.current_user = User.new(id: 3, name: 'Pete', admin: false)
- render json: new_post, serializer: PostSerializer, adapter: :json, scope: current_user
- end
-
- private
-
- def new_post
- Post.new(id: 4, title: 'Title')
- end
- end
- tests PostViewContextTestController
-
- def test_nil_serialization_scope
- assert_nil @controller._serialization_scope
- end
-
- def test_nil_serialization_scope_object
- assert_nil @controller.serialization_scope
- end
-
- def test_nil_scope
- exception_matcher = /current_user/
- exception = assert_raises(NameError) do
- get :render_post_with_no_scope
- end
- assert_match exception_matcher, exception.message
- end
-
- def test_serialization_scope_is_and_nil_scope_passed_in_current_user
- get :render_post_with_passed_in_scope
- expected_json = {
- post: {
- id: 4,
- title: 'Title',
- body: "The 'scope' is the 'current_user': true",
- comments: [
- { id: 2, body: 'Scoped' }
- ]
- }
- }.to_json
- assert_equal expected_json, @response.body
- end
-
- def test_serialization_scope_is_nil_and_scope_passed_in_current_user_without_scope_name
- exception_matcher = /current_user/
- exception = assert_raises(NameError) do
- get :render_post_with_passed_in_scope_without_scope_name
- end
- assert_match exception_matcher, exception.message
- end
- end
-end
diff --git a/test/action_controller/serialization_test.rb b/test/action_controller/serialization_test.rb
deleted file mode 100644
index dfd72b42..00000000
--- a/test/action_controller/serialization_test.rb
+++ /dev/null
@@ -1,472 +0,0 @@
-require 'test_helper'
-
-module ActionController
- module Serialization
- class ImplicitSerializerTest < ActionController::TestCase
- class ImplicitSerializationTestController < ActionController::Base
- include SerializationTesting
- def render_using_implicit_serializer
- @profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- render json: @profile
- end
-
- def render_using_default_adapter_root
- @profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- render json: @profile
- end
-
- def render_array_using_custom_root
- @profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- render json: [@profile], root: 'custom_root'
- end
-
- def render_array_that_is_empty_using_custom_root
- render json: [], root: 'custom_root'
- end
-
- def render_object_using_custom_root
- @profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- render json: @profile, root: 'custom_root'
- end
-
- def render_array_using_implicit_serializer
- array = [
- Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
- Profile.new(name: 'Name 2', description: 'Description 2', comments: 'Comments 2')
- ]
- render json: array
- end
-
- def render_array_using_implicit_serializer_and_meta
- @profiles = [
- Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- ]
- render json: @profiles, meta: { total: 10 }
- end
-
- def render_array_using_implicit_serializer_and_links
- with_adapter ActiveModelSerializers::Adapter::JsonApi do
- @profiles = [
- Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- ]
-
- render json: @profiles, links: { self: 'http://example.com/api/profiles/1' }
- end
- end
-
- def render_object_with_cache_enabled
- @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @author = Author.new(id: 1, name: 'Joao Moura.')
- @post = Post.new(id: 1, title: 'New Post', body: 'Body', comments: [@comment], author: @author)
-
- generate_cached_serializer(@post)
-
- @post.title = 'ZOMG a New Post'
- render json: @post
- end
-
- def render_json_object_without_serializer
- render json: { error: 'Result is Invalid' }
- end
-
- def render_json_array_object_without_serializer
- render json: [{ error: 'Result is Invalid' }]
- end
-
- def update_and_render_object_with_cache_enabled
- @post.updated_at = Time.zone.now
-
- generate_cached_serializer(@post)
- render json: @post
- end
-
- def render_object_expired_with_cache_enabled
- comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- author = Author.new(id: 1, name: 'Joao Moura.')
- post = Post.new(id: 1, title: 'New Post', body: 'Body', comments: [comment], author: author)
-
- generate_cached_serializer(post)
-
- post.title = 'ZOMG a New Post'
-
- expires_in = [
- PostSerializer._cache_options[:expires_in],
- CommentSerializer._cache_options[:expires_in]
- ].max + 200
-
- Timecop.travel(Time.zone.now + expires_in) do
- render json: post
- end
- end
-
- def render_changed_object_with_cache_enabled
- comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- author = Author.new(id: 1, name: 'Joao Moura.')
- post = Post.new(id: 1, title: 'ZOMG a New Post', body: 'Body', comments: [comment], author: author)
-
- render json: post
- end
-
- def render_fragment_changed_object_with_only_cache_enabled
- author = Author.new(id: 1, name: 'Joao Moura.')
- role = Role.new(id: 42, name: 'ZOMG A ROLE', description: 'DESCRIPTION HERE', author: author)
-
- generate_cached_serializer(role)
- role.name = 'lol'
- role.description = 'HUEHUEBRBR'
-
- render json: role
- end
-
- def render_fragment_changed_object_with_except_cache_enabled
- author = Author.new(id: 1, name: 'Joao Moura.')
- bio = Bio.new(id: 42, content: 'ZOMG A ROLE', rating: 5, author: author)
-
- generate_cached_serializer(bio)
- bio.content = 'lol'
- bio.rating = 0
-
- render json: bio
- end
-
- def render_fragment_changed_object_with_relationship
- comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- comment2 = Comment.new(id: 1, body: 'ZOMG AN UPDATED-BUT-NOT-CACHE-EXPIRED COMMENT')
- like = Like.new(id: 1, likeable: comment, time: 3.days.ago)
-
- generate_cached_serializer(like)
- like.likeable = comment2
- like.time = Time.zone.now.to_s
-
- render json: like
- end
- end
-
- tests ImplicitSerializationTestController
-
- # We just have Null for now, this will change
- def test_render_using_implicit_serializer
- get :render_using_implicit_serializer
-
- expected = {
- name: 'Name 1',
- description: 'Description 1'
- }
-
- assert_equal 'application/json', @response.content_type
- assert_equal expected.to_json, @response.body
- end
-
- def test_render_using_default_root
- with_adapter :json_api do
- get :render_using_default_adapter_root
- end
- expected = {
- data: {
- id: @controller.instance_variable_get(:@profile).id.to_s,
- type: 'profiles',
- attributes: {
- name: 'Name 1',
- description: 'Description 1'
- }
- }
- }
-
- assert_equal 'application/json', @response.content_type
- assert_equal expected.to_json, @response.body
- end
-
- def test_render_array_using_custom_root
- with_adapter :json do
- get :render_array_using_custom_root
- end
- expected = { custom_root: [{ name: 'Name 1', description: 'Description 1' }] }
- assert_equal 'application/json', @response.content_type
- assert_equal expected.to_json, @response.body
- end
-
- def test_render_array_that_is_empty_using_custom_root
- with_adapter :json do
- get :render_array_that_is_empty_using_custom_root
- end
-
- expected = { custom_root: [] }
- assert_equal 'application/json', @response.content_type
- assert_equal expected.to_json, @response.body
- end
-
- def test_render_object_using_custom_root
- with_adapter :json do
- get :render_object_using_custom_root
- end
-
- expected = { custom_root: { name: 'Name 1', description: 'Description 1' } }
- assert_equal 'application/json', @response.content_type
- assert_equal expected.to_json, @response.body
- end
-
- def test_render_json_object_without_serializer
- get :render_json_object_without_serializer
-
- assert_equal 'application/json', @response.content_type
- expected_body = { error: 'Result is Invalid' }
- assert_equal expected_body.to_json, @response.body
- end
-
- def test_render_json_array_object_without_serializer
- get :render_json_array_object_without_serializer
-
- assert_equal 'application/json', @response.content_type
- expected_body = [{ error: 'Result is Invalid' }]
- assert_equal expected_body.to_json, @response.body
- end
-
- def test_render_array_using_implicit_serializer
- get :render_array_using_implicit_serializer
- assert_equal 'application/json', @response.content_type
-
- expected = [
- {
- name: 'Name 1',
- description: 'Description 1'
- },
- {
- name: 'Name 2',
- description: 'Description 2'
- }
- ]
-
- assert_equal expected.to_json, @response.body
- end
-
- def test_render_array_using_implicit_serializer_and_meta
- with_adapter :json_api do
- get :render_array_using_implicit_serializer_and_meta
- end
- expected = {
- data: [
- {
- id: @controller.instance_variable_get(:@profiles).first.id.to_s,
- type: 'profiles',
- attributes: {
- name: 'Name 1',
- description: 'Description 1'
- }
- }
- ],
- meta: {
- total: 10
- }
- }
-
- assert_equal 'application/json', @response.content_type
- assert_equal expected.to_json, @response.body
- end
-
- def test_render_array_using_implicit_serializer_and_links
- get :render_array_using_implicit_serializer_and_links
-
- expected = {
- data: [
- {
- id: @controller.instance_variable_get(:@profiles).first.id.to_s,
- type: 'profiles',
- attributes: {
- name: 'Name 1',
- description: 'Description 1'
- }
- }
- ],
- links: {
- self: 'http://example.com/api/profiles/1'
- }
- }
-
- assert_equal 'application/json', @response.content_type
- assert_equal expected.to_json, @response.body
- end
-
- def test_render_with_cache_enable
- expected = {
- id: 1,
- title: 'New Post',
- body: 'Body',
- comments: [
- {
- id: 1,
- body: 'ZOMG A COMMENT'
- }
- ],
- blog: {
- id: 999,
- name: 'Custom blog'
- },
- author: {
- id: 1,
- name: 'Joao Moura.'
- }
- }
-
- ActionController::Base.cache_store.clear
- Timecop.freeze(Time.zone.now) do
- get :render_object_with_cache_enabled
-
- assert_equal 'application/json', @response.content_type
- assert_equal expected.to_json, @response.body
-
- get :render_changed_object_with_cache_enabled
- assert_equal expected.to_json, @response.body
- end
-
- ActionController::Base.cache_store.clear
- get :render_changed_object_with_cache_enabled
- assert_not_equal expected.to_json, @response.body
- end
-
- def test_render_with_cache_enable_and_expired
- ActionController::Base.cache_store.clear
- get :render_object_expired_with_cache_enabled
-
- expected = {
- id: 1,
- title: 'ZOMG a New Post',
- body: 'Body',
- comments: [
- {
- id: 1,
- body: 'ZOMG A COMMENT'
- }
- ],
- blog: {
- id: 999,
- name: 'Custom blog'
- },
- author: {
- id: 1,
- name: 'Joao Moura.'
- }
- }
-
- assert_equal 'application/json', @response.content_type
- actual = @response.body
- expected = expected.to_json
- if ENV['APPVEYOR'] && actual != expected
- skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)')
- else
- assert_equal actual, expected
- end
- end
-
- def test_render_with_fragment_only_cache_enable
- ActionController::Base.cache_store.clear
- get :render_fragment_changed_object_with_only_cache_enabled
- response = JSON.parse(@response.body)
-
- assert_equal 'application/json', @response.content_type
- assert_equal 'ZOMG A ROLE', response['name']
- assert_equal 'HUEHUEBRBR', response['description']
- end
-
- def test_render_with_fragment_except_cache_enable
- ActionController::Base.cache_store.clear
- get :render_fragment_changed_object_with_except_cache_enabled
- response = JSON.parse(@response.body)
-
- assert_equal 'application/json', @response.content_type
- assert_equal 5, response['rating']
- assert_equal 'lol', response['content']
- end
-
- def test_render_fragment_changed_object_with_relationship
- ActionController::Base.cache_store.clear
-
- Timecop.freeze(Time.zone.now) do
- get :render_fragment_changed_object_with_relationship
- response = JSON.parse(@response.body)
-
- expected_return = {
- 'id' => 1,
- 'time' => Time.zone.now.to_s,
- 'likeable' => {
- 'id' => 1,
- 'body' => 'ZOMG A COMMENT'
- }
- }
-
- assert_equal 'application/json', @response.content_type
- assert_equal expected_return, response
- end
- end
-
- def test_cache_expiration_on_update
- ActionController::Base.cache_store.clear
- get :render_object_with_cache_enabled
-
- expected = {
- id: 1,
- title: 'ZOMG a New Post',
- body: 'Body',
- comments: [
- {
- id: 1,
- body: 'ZOMG A COMMENT'
- }
- ],
- blog: {
- id: 999,
- name: 'Custom blog'
- },
- author: {
- id: 1,
- name: 'Joao Moura.'
- }
- }
-
- get :update_and_render_object_with_cache_enabled
-
- assert_equal 'application/json', @response.content_type
- actual = @response.body
- expected = expected.to_json
- if ENV['APPVEYOR'] && actual != expected
- skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)')
- else
- assert_equal actual, expected
- end
- end
-
- def test_warn_overridding_use_adapter_as_falsy_on_controller_instance
- controller = Class.new(ImplicitSerializationTestController) do
- def use_adapter?
- false
- end
- end.new
- assert_output(nil, /adapter: false/) do
- controller.get_serializer(Profile.new)
- end
- end
-
- def test_dont_warn_overridding_use_adapter_as_truthy_on_controller_instance
- controller = Class.new(ImplicitSerializationTestController) do
- def use_adapter?
- true
- end
- end.new
- assert_output(nil, '') do
- controller.get_serializer(Profile.new)
- end
- end
-
- def test_render_event_is_emitted
- subscriber = ::ActiveSupport::Notifications.subscribe('render.active_model_serializers') do |name|
- @name = name
- end
-
- get :render_using_implicit_serializer
-
- assert_equal 'render.active_model_serializers', @name
- ensure
- ActiveSupport::Notifications.unsubscribe(subscriber) if subscriber
- end
- end
- end
-end
diff --git a/test/active_model_serializers/adapter_for_test.rb b/test/active_model_serializers/adapter_for_test.rb
deleted file mode 100644
index 1439b987..00000000
--- a/test/active_model_serializers/adapter_for_test.rb
+++ /dev/null
@@ -1,208 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- class AdapterForTest < ::ActiveSupport::TestCase
- UnknownAdapterError = ::ActiveModelSerializers::Adapter::UnknownAdapterError
-
- def test_serializer_adapter_returns_configured_adapter
- assert_output(nil, /ActiveModelSerializers::Adapter.configured_adapter/) do
- assert_equal ActiveModelSerializers::Adapter.configured_adapter, ActiveModel::Serializer.adapter
- end
- end
-
- def test_returns_default_adapter
- with_adapter_config_setup do
- adapter = ActiveModelSerializers::Adapter.configured_adapter
- assert_equal ActiveModelSerializers::Adapter::Attributes, adapter
- end
- end
-
- def test_overwrite_adapter_with_symbol
- with_adapter_config_setup do
- ActiveModelSerializers.config.adapter = :null
-
- adapter = ActiveModelSerializers::Adapter.configured_adapter
- assert_equal ActiveModelSerializers::Adapter::Null, adapter
- end
- end
-
- def test_overwrite_adapter_with_camelcased_symbol
- with_adapter_config_setup do
- ActiveModelSerializers.config.adapter = :JsonApi
-
- adapter = ActiveModelSerializers::Adapter.configured_adapter
- assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter
- end
- end
-
- def test_overwrite_adapter_with_string
- with_adapter_config_setup do
- ActiveModelSerializers.config.adapter = 'json_api'
-
- adapter = ActiveModelSerializers::Adapter.configured_adapter
- assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter
- end
- end
-
- def test_overwrite_adapter_with_a_camelcased_string
- with_adapter_config_setup do
- ActiveModelSerializers.config.adapter = 'JsonApi'
-
- adapter = ActiveModelSerializers::Adapter.configured_adapter
- assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter
- end
- end
-
- def test_overwrite_adapter_with_class
- with_adapter_config_setup do
- ActiveModelSerializers.config.adapter = ActiveModelSerializers::Adapter::Null
-
- adapter = ActiveModelSerializers::Adapter.configured_adapter
- assert_equal ActiveModelSerializers::Adapter::Null, adapter
- end
- end
-
- def test_raises_exception_if_invalid_symbol_given
- with_adapter_config_setup do
- ActiveModelSerializers.config.adapter = :unknown
-
- assert_raises UnknownAdapterError do
- ActiveModelSerializers::Adapter.configured_adapter
- end
- end
- end
-
- def test_raises_exception_if_it_does_not_know_hot_to_infer_adapter
- with_adapter_config_setup do
- ActiveModelSerializers.config.adapter = 42
-
- assert_raises UnknownAdapterError do
- ActiveModelSerializers::Adapter.configured_adapter
- end
- end
- end
-
- def test_adapter_class_for_known_adapter
- klass = ActiveModelSerializers::Adapter.adapter_class(:json_api)
- assert_equal ActiveModelSerializers::Adapter::JsonApi, klass
- end
-
- def test_adapter_class_for_unknown_adapter
- assert_raises UnknownAdapterError do
- ActiveModelSerializers::Adapter.adapter_class(:json_simple)
- end
- end
-
- def test_adapter_map
- expected_adapter_map = {
- 'null'.freeze => ActiveModelSerializers::Adapter::Null,
- 'json'.freeze => ActiveModelSerializers::Adapter::Json,
- 'attributes'.freeze => ActiveModelSerializers::Adapter::Attributes,
- 'json_api'.freeze => ActiveModelSerializers::Adapter::JsonApi
- }
- actual = ActiveModelSerializers::Adapter.adapter_map
- assert_equal actual, expected_adapter_map
- end
-
- def test_adapters
- assert_equal ActiveModelSerializers::Adapter.adapters.sort, [
- 'attributes'.freeze,
- 'json'.freeze,
- 'json_api'.freeze,
- 'null'.freeze
- ]
- end
-
- def test_lookup_adapter_by_string_name
- assert_equal ActiveModelSerializers::Adapter.lookup('json'.freeze), ActiveModelSerializers::Adapter::Json
- end
-
- def test_lookup_adapter_by_symbol_name
- assert_equal ActiveModelSerializers::Adapter.lookup(:json), ActiveModelSerializers::Adapter::Json
- end
-
- def test_lookup_adapter_by_class
- klass = ActiveModelSerializers::Adapter::Json
- assert_equal ActiveModelSerializers::Adapter.lookup(klass), klass
- end
-
- def test_lookup_adapter_from_environment_registers_adapter
- ActiveModelSerializers::Adapter.const_set(:AdapterFromEnvironment, Class.new)
- klass = ::ActiveModelSerializers::Adapter::AdapterFromEnvironment
- name = 'adapter_from_environment'.freeze
- assert_equal ActiveModelSerializers::Adapter.lookup(name), klass
- assert ActiveModelSerializers::Adapter.adapters.include?(name)
- ensure
- ActiveModelSerializers::Adapter.adapter_map.delete(name)
- ActiveModelSerializers::Adapter.send(:remove_const, :AdapterFromEnvironment)
- end
-
- def test_lookup_adapter_for_unknown_name
- assert_raises UnknownAdapterError do
- ActiveModelSerializers::Adapter.lookup(:json_simple)
- end
- end
-
- def test_adapter
- assert_equal ActiveModelSerializers.config.adapter, :attributes
- assert_equal ActiveModelSerializers::Adapter.configured_adapter, ActiveModelSerializers::Adapter::Attributes
- end
-
- def test_register_adapter
- new_adapter_name = :foo
- new_adapter_klass = Class.new
- ActiveModelSerializers::Adapter.register(new_adapter_name, new_adapter_klass)
- assert ActiveModelSerializers::Adapter.adapters.include?('foo'.freeze)
- assert ActiveModelSerializers::Adapter.lookup(:foo), new_adapter_klass
- ensure
- ActiveModelSerializers::Adapter.adapter_map.delete(new_adapter_name.to_s)
- end
-
- def test_inherited_adapter_hooks_register_adapter
- Object.const_set(:MyAdapter, Class.new)
- my_adapter = MyAdapter
- ActiveModelSerializers::Adapter::Base.inherited(my_adapter)
- assert_equal ActiveModelSerializers::Adapter.lookup(:my_adapter), my_adapter
- ensure
- ActiveModelSerializers::Adapter.adapter_map.delete('my_adapter'.freeze)
- Object.send(:remove_const, :MyAdapter)
- end
-
- def test_inherited_adapter_hooks_register_namespaced_adapter
- Object.const_set(:MyNamespace, Module.new)
- MyNamespace.const_set(:MyAdapter, Class.new)
- my_adapter = MyNamespace::MyAdapter
- ActiveModelSerializers::Adapter::Base.inherited(my_adapter)
- assert_equal ActiveModelSerializers::Adapter.lookup(:'my_namespace/my_adapter'), my_adapter
- ensure
- ActiveModelSerializers::Adapter.adapter_map.delete('my_namespace/my_adapter'.freeze)
- MyNamespace.send(:remove_const, :MyAdapter)
- Object.send(:remove_const, :MyNamespace)
- end
-
- def test_inherited_adapter_hooks_register_subclass_of_registered_adapter
- Object.const_set(:MyAdapter, Class.new)
- my_adapter = MyAdapter
- Object.const_set(:MySubclassedAdapter, Class.new(MyAdapter))
- my_subclassed_adapter = MySubclassedAdapter
- ActiveModelSerializers::Adapter::Base.inherited(my_adapter)
- ActiveModelSerializers::Adapter::Base.inherited(my_subclassed_adapter)
- assert_equal ActiveModelSerializers::Adapter.lookup(:my_adapter), my_adapter
- assert_equal ActiveModelSerializers::Adapter.lookup(:my_subclassed_adapter), my_subclassed_adapter
- ensure
- ActiveModelSerializers::Adapter.adapter_map.delete('my_adapter'.freeze)
- ActiveModelSerializers::Adapter.adapter_map.delete('my_subclassed_adapter'.freeze)
- Object.send(:remove_const, :MyAdapter)
- Object.send(:remove_const, :MySubclassedAdapter)
- end
-
- private
-
- def with_adapter_config_setup
- previous_adapter = ActiveModelSerializers.config.adapter
- yield
- ensure
- ActiveModelSerializers.config.adapter = previous_adapter
- end
- end
-end
diff --git a/test/active_model_serializers/json_pointer_test.rb b/test/active_model_serializers/json_pointer_test.rb
deleted file mode 100644
index 60619ee6..00000000
--- a/test/active_model_serializers/json_pointer_test.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- class JsonPointerTest < ActiveSupport::TestCase
- def test_attribute_pointer
- attribute_name = 'title'
- pointer = ActiveModelSerializers::JsonPointer.new(:attribute, attribute_name)
- assert_equal '/data/attributes/title', pointer
- end
-
- def test_primary_data_pointer
- pointer = ActiveModelSerializers::JsonPointer.new(:primary_data)
- assert_equal '/data', pointer
- end
-
- def test_unknown_data_pointer
- assert_raises(TypeError) do
- ActiveModelSerializers::JsonPointer.new(:unknown)
- end
- end
- end
-end
diff --git a/test/active_model_serializers/logging_test.rb b/test/active_model_serializers/logging_test.rb
deleted file mode 100644
index 95e61682..00000000
--- a/test/active_model_serializers/logging_test.rb
+++ /dev/null
@@ -1,77 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class LoggingTest < ActiveSupport::TestCase
- class TestLogger < ActiveSupport::Logger
- def initialize
- @file = StringIO.new
- super(@file)
- end
-
- def messages
- @file.rewind
- @file.read
- end
- end
-
- def setup
- @author = Author.new(name: 'Steve K.')
- @post = Post.new(title: 'New Post', body: 'Body')
- @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @post.comments = [@comment]
- @comment.post = @post
- @post.author = @author
- @author.posts = [@post]
- @post_serializer = PostSerializer.new(@post, custom_options: true)
-
- @old_logger = ActiveModelSerializers.logger
- @logger = ActiveSupport::TaggedLogging.new(TestLogger.new)
- logger @logger
- end
-
- def teardown
- logger @old_logger
- end
-
- def logger(logger)
- ActiveModelSerializers.logger = logger
- end
-
- def test_uses_ams_as_tag
- ActiveModelSerializers::SerializableResource.new(@post).serializable_hash
- assert_match(/\[active_model_serializers\]/, @logger.messages)
- end
-
- def test_logs_when_call_serializable_hash
- ActiveModelSerializers::SerializableResource.new(@post).serializable_hash
- assert_match(/Rendered/, @logger.messages)
- end
-
- def test_logs_when_call_as_json
- ActiveModelSerializers::SerializableResource.new(@post).as_json
- assert_match(/Rendered/, @logger.messages)
- end
-
- def test_logs_when_call_to_json
- ActiveModelSerializers::SerializableResource.new(@post).to_json
- assert_match(/Rendered/, @logger.messages)
- end
-
- def test_logs_correct_serializer
- ActiveModelSerializers::SerializableResource.new(@post).serializable_hash
- assert_match(/PostSerializer/, @logger.messages)
- end
-
- def test_logs_correct_adapter
- ActiveModelSerializers::SerializableResource.new(@post).serializable_hash
- assert_match(/ActiveModelSerializers::Adapter::Attributes/, @logger.messages)
- end
-
- def test_logs_the_duration
- ActiveModelSerializers::SerializableResource.new(@post).serializable_hash
- assert_match(/\(\d+\.\d+ms\)/, @logger.messages)
- end
- end
- end
-end
diff --git a/test/active_model_serializers/model_test.rb b/test/active_model_serializers/model_test.rb
deleted file mode 100644
index 6a8a29af..00000000
--- a/test/active_model_serializers/model_test.rb
+++ /dev/null
@@ -1,142 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- class ModelTest < ActiveSupport::TestCase
- include ActiveModel::Serializer::Lint::Tests
-
- setup do
- @resource = ActiveModelSerializers::Model.new
- end
-
- def test_initialization_with_string_keys
- klass = Class.new(ActiveModelSerializers::Model) do
- attributes :key
- end
- value = 'value'
-
- model_instance = klass.new('key' => value)
-
- assert_equal model_instance.read_attribute_for_serialization(:key), value
- end
-
- def test_attributes_can_be_read_for_serialization
- klass = Class.new(ActiveModelSerializers::Model) do
- attributes :one, :two, :three
- end
- original_attributes = { one: 1, two: 2, three: 3 }
- original_instance = klass.new(original_attributes)
-
- # Initial value
- instance = original_instance
- expected_attributes = { one: 1, two: 2, three: 3 }.with_indifferent_access
- assert_equal expected_attributes, instance.attributes
- assert_equal 1, instance.one
- assert_equal 1, instance.read_attribute_for_serialization(:one)
-
- # FIXME: Change via accessor has no effect on attributes.
- instance = original_instance.dup
- instance.one = :not_one
- assert_equal expected_attributes, instance.attributes
- assert_equal :not_one, instance.one
- assert_equal :not_one, instance.read_attribute_for_serialization(:one)
-
- # FIXME: Change via mutating attributes
- instance = original_instance.dup
- instance.attributes[:one] = :not_one
- expected_attributes = { one: :not_one, two: 2, three: 3 }.with_indifferent_access
- assert_equal expected_attributes, instance.attributes
- assert_equal 1, instance.one
- assert_equal 1, instance.read_attribute_for_serialization(:one)
- end
-
- def test_attributes_can_be_read_for_serialization_with_attributes_accessors_fix
- klass = Class.new(ActiveModelSerializers::Model) do
- derive_attributes_from_names_and_fix_accessors
- attributes :one, :two, :three
- end
- original_attributes = { one: 1, two: 2, three: 3 }
- original_instance = klass.new(original_attributes)
-
- # Initial value
- instance = original_instance
- expected_attributes = { one: 1, two: 2, three: 3 }.with_indifferent_access
- assert_equal expected_attributes, instance.attributes
- assert_equal 1, instance.one
- assert_equal 1, instance.read_attribute_for_serialization(:one)
-
- expected_attributes = { one: :not_one, two: 2, three: 3 }.with_indifferent_access
- # Change via accessor
- instance = original_instance.dup
- instance.one = :not_one
- assert_equal expected_attributes, instance.attributes
- assert_equal :not_one, instance.one
- assert_equal :not_one, instance.read_attribute_for_serialization(:one)
-
- # Attributes frozen
- assert instance.attributes.frozen?
- end
-
- def test_id_attribute_can_be_read_for_serialization
- klass = Class.new(ActiveModelSerializers::Model) do
- attributes :id, :one, :two, :three
- end
- self.class.const_set(:SomeTestModel, klass)
- original_attributes = { id: :ego, one: 1, two: 2, three: 3 }
- original_instance = klass.new(original_attributes)
-
- # Initial value
- instance = original_instance.dup
- expected_attributes = { id: :ego, one: 1, two: 2, three: 3 }.with_indifferent_access
- assert_equal expected_attributes, instance.attributes
- assert_equal :ego, instance.id
- assert_equal :ego, instance.read_attribute_for_serialization(:id)
-
- # FIXME: Change via accessor has no effect on attributes.
- instance = original_instance.dup
- instance.id = :superego
- assert_equal expected_attributes, instance.attributes
- assert_equal :superego, instance.id
- assert_equal :superego, instance.read_attribute_for_serialization(:id)
-
- # FIXME: Change via mutating attributes
- instance = original_instance.dup
- instance.attributes[:id] = :superego
- expected_attributes = { id: :superego, one: 1, two: 2, three: 3 }.with_indifferent_access
- assert_equal expected_attributes, instance.attributes
- assert_equal :ego, instance.id
- assert_equal :ego, instance.read_attribute_for_serialization(:id)
- ensure
- self.class.send(:remove_const, :SomeTestModel)
- end
-
- def test_id_attribute_can_be_read_for_serialization_with_attributes_accessors_fix
- klass = Class.new(ActiveModelSerializers::Model) do
- derive_attributes_from_names_and_fix_accessors
- attributes :id, :one, :two, :three
- end
- self.class.const_set(:SomeTestModel, klass)
- original_attributes = { id: :ego, one: 1, two: 2, three: 3 }
- original_instance = klass.new(original_attributes)
-
- # Initial value
- instance = original_instance.dup
- expected_attributes = { id: :ego, one: 1, two: 2, three: 3 }.with_indifferent_access
- assert_equal expected_attributes, instance.attributes
- assert_equal :ego, instance.id
- assert_equal :ego, instance.read_attribute_for_serialization(:id)
-
- expected_attributes = { id: :superego, one: 1, two: 2, three: 3 }.with_indifferent_access
- # Change via accessor
- instance = original_instance.dup
- instance.id = :superego
- assert_equal expected_attributes, instance.attributes
- assert_equal :superego, instance.id
- assert_equal :superego, instance.read_attribute_for_serialization(:id)
-
- # Attributes frozen
- assert instance.attributes.frozen?
- ensure
- self.class.send(:remove_const, :SomeTestModel)
- end
- end
-end
diff --git a/test/active_model_serializers/railtie_test_isolated.rb b/test/active_model_serializers/railtie_test_isolated.rb
deleted file mode 100644
index 1044fc8b..00000000
--- a/test/active_model_serializers/railtie_test_isolated.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-# Execute this test in isolation
-require 'support/isolated_unit'
-
-class RailtieTest < ActiveSupport::TestCase
- include ActiveSupport::Testing::Isolation
-
- class WithRailsRequiredFirst < RailtieTest
- setup do
- require 'rails'
- require 'active_model_serializers'
- make_basic_app do |app|
- app.config.action_controller.perform_caching = true
- end
- end
-
- test 'mixes ActionController::Serialization into ActionController::Base' do
- assert ActionController.const_defined?(:Serialization),
- "ActionController::Serialization should be defined, but isn't"
- assert ::ActionController::Base.included_modules.include?(::ActionController::Serialization),
- "ActionController::Serialization should be included in ActionController::Base, but isn't"
- end
-
- test 'prepares url_helpers for SerializationContext' do
- assert ActiveModelSerializers::SerializationContext.url_helpers.respond_to? :url_for
- assert_equal Rails.application.routes.default_url_options,
- ActiveModelSerializers::SerializationContext.default_url_options
- end
-
- test 'sets the ActiveModelSerializers.logger to Rails.logger' do
- refute_nil Rails.logger
- refute_nil ActiveModelSerializers.logger
- assert_equal Rails.logger, ActiveModelSerializers.logger
- end
-
- test 'it is configured for caching' do
- assert_equal ActionController::Base.cache_store, ActiveModelSerializers.config.cache_store
- assert_equal true, Rails.configuration.action_controller.perform_caching
- assert_equal true, ActiveModelSerializers.config.perform_caching
- end
- end
-
- class WithoutRailsRequiredFirst < RailtieTest
- setup do
- require 'active_model_serializers'
- make_basic_app do |app|
- app.config.action_controller.perform_caching = true
- end
- end
-
- test 'does not mix ActionController::Serialization into ActionController::Base' do
- refute ActionController.const_defined?(:Serialization),
- 'ActionController::Serialization should not be defined, but is'
- end
-
- test 'has its own logger at ActiveModelSerializers.logger' do
- refute_nil Rails.logger
- refute_nil ActiveModelSerializers.logger
- refute_equal Rails.logger, ActiveModelSerializers.logger
- end
-
- test 'it is not configured for caching' do
- refute_nil ActionController::Base.cache_store
- assert_nil ActiveModelSerializers.config.cache_store
- assert_equal true, Rails.configuration.action_controller.perform_caching
- assert_nil ActiveModelSerializers.config.perform_caching
- end
- end
-end
diff --git a/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb b/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb
deleted file mode 100644
index 30542408..00000000
--- a/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb
+++ /dev/null
@@ -1,161 +0,0 @@
-require 'support/isolated_unit'
-require 'minitest/mock'
-require 'action_dispatch'
-require 'action_controller'
-
-class JsonApiRendererTest < ActionDispatch::IntegrationTest
- include ActiveSupport::Testing::Isolation
-
- class TestController < ActionController::Base
- class << self
- attr_accessor :last_request_parameters
- end
-
- def render_with_jsonapi_renderer
- permitted_params = params.permit(data: [:id, :type, attributes: [:name]])
- permitted_params = permitted_params.to_h.with_indifferent_access
- attributes =
- if permitted_params[:data]
- permitted_params[:data][:attributes].merge(id: permitted_params[:data][:id])
- else
- # Rails returns empty params when no mime type can be negotiated.
- # (Until https://github.com/rails/rails/pull/26632 is reviewed.)
- permitted_params
- end
- author = Author.new(attributes)
- render jsonapi: author
- end
-
- def parse
- self.class.last_request_parameters = request.request_parameters
- head :ok
- end
- end
-
- def teardown
- TestController.last_request_parameters = nil
- end
-
- def assert_parses(expected, actual, headers = {})
- post '/parse', params: actual, headers: headers
- assert_response :ok
- assert_equal(expected, TestController.last_request_parameters)
- end
-
- def define_author_model_and_serializer
- TestController.const_set(:Author, Class.new(ActiveModelSerializers::Model) do
- attributes :id, :name
- end)
- TestController.const_set(:AuthorSerializer, Class.new(ActiveModel::Serializer) do
- type 'users'
- attribute :id
- attribute :name
- end)
- end
-
- class WithoutRenderer < JsonApiRendererTest
- setup do
- require 'rails'
- require 'active_record'
- require 'support/rails5_shims'
- require 'active_model_serializers'
- require 'fixtures/poro'
-
- make_basic_app
-
- Rails.application.routes.draw do
- ActiveSupport::Deprecation.silence do
- match ':action', to: TestController, via: [:get, :post]
- end
- end
- define_author_model_and_serializer
- end
-
- def test_jsonapi_parser_not_registered
- parsers = if Rails::VERSION::MAJOR >= 5
- ActionDispatch::Request.parameter_parsers
- else
- ActionDispatch::ParamsParser::DEFAULT_PARSERS
- end
- assert_nil parsers[Mime[:jsonapi]]
- end
-
- def test_jsonapi_renderer_not_registered
- payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}'
- headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
- post '/render_with_jsonapi_renderer', params: payload, headers: headers
- assert_equal '', response.body
- assert_equal 500, response.status
- assert_equal ActionView::MissingTemplate, request.env['action_dispatch.exception'].class
- end
-
- def test_jsonapi_parser
- assert_parses(
- {},
- '',
- 'CONTENT_TYPE' => 'application/vnd.api+json'
- )
- end
- end
-
- class WithRenderer < JsonApiRendererTest
- setup do
- require 'rails'
- require 'active_record'
- require 'support/rails5_shims'
- require 'active_model_serializers'
- require 'fixtures/poro'
- require 'active_model_serializers/register_jsonapi_renderer'
-
- make_basic_app
-
- Rails.application.routes.draw do
- ActiveSupport::Deprecation.silence do
- match ':action', to: TestController, via: [:get, :post]
- end
- end
- define_author_model_and_serializer
- end
-
- def test_jsonapi_parser_registered
- if Rails::VERSION::MAJOR >= 5
- parsers = ActionDispatch::Request.parameter_parsers
- assert_equal Proc, parsers[:jsonapi].class
- else
- parsers = ActionDispatch::ParamsParser::DEFAULT_PARSERS
- assert_equal Proc, parsers[Mime[:jsonapi]].class
- end
- end
-
- def test_jsonapi_renderer_registered
- expected = {
- 'data' => {
- 'id' => '36c9c04e-86b1-4636-a5b0-8616672d1765',
- 'type' => 'users',
- 'attributes' => { 'name' => 'Johnny Rico' }
- }
- }
-
- payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}'
- headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
- post '/render_with_jsonapi_renderer', params: payload, headers: headers
- assert_equal expected.to_json, response.body
- end
-
- def test_jsonapi_parser
- assert_parses(
- {
- 'data' => {
- 'attributes' => {
- 'name' => 'John Doe'
- },
- 'type' => 'users',
- 'id' => '36c9c04e-86b1-4636-a5b0-8616672d1765'
- }
- },
- '{"data": {"attributes": {"name": "John Doe"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}',
- 'CONTENT_TYPE' => 'application/vnd.api+json'
- )
- end
- end
-end
diff --git a/test/active_model_serializers/serialization_context_test_isolated.rb b/test/active_model_serializers/serialization_context_test_isolated.rb
deleted file mode 100644
index 5720e84a..00000000
--- a/test/active_model_serializers/serialization_context_test_isolated.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# Execute this test in isolation
-require 'support/isolated_unit'
-require 'minitest/mock'
-
-class SerializationContextTest < ActiveSupport::TestCase
- include ActiveSupport::Testing::Isolation
-
- class WithRails < SerializationContextTest
- def create_request
- request = ActionDispatch::Request.new({})
- def request.original_url
- 'http://example.com/articles?page=2'
- end
-
- def request.query_parameters
- { 'page' => 2 }
- end
- request
- end
-
- setup do
- require 'rails'
- require 'active_model_serializers'
- make_basic_app
- @context = ActiveModelSerializers::SerializationContext.new(create_request)
- end
-
- test 'create context with request url and query parameters' do
- assert_equal @context.request_url, 'http://example.com/articles'
- assert_equal @context.query_parameters, 'page' => 2
- end
-
- test 'url_helpers is set up for Rails url_helpers' do
- assert_equal Module, ActiveModelSerializers::SerializationContext.url_helpers.class
- assert ActiveModelSerializers::SerializationContext.url_helpers.respond_to? :url_for
- end
-
- test 'default_url_options returns Rails.application.routes.default_url_options' do
- assert_equal Rails.application.routes.default_url_options,
- ActiveModelSerializers::SerializationContext.default_url_options
- end
- end
-
- class WithoutRails < SerializationContextTest
- def create_request
- {
- request_url: 'http://example.com/articles',
- query_parameters: { 'page' => 2 }
- }
- end
-
- setup do
- require 'active_model_serializers/serialization_context'
- @context = ActiveModelSerializers::SerializationContext.new(create_request)
- end
-
- test 'create context with request url and query parameters' do
- assert_equal @context.request_url, 'http://example.com/articles'
- assert_equal @context.query_parameters, 'page' => 2
- end
-
- test 'url_helpers is a module when Rails is not present' do
- assert_equal Module, ActiveModelSerializers::SerializationContext.url_helpers.class
- refute ActiveModelSerializers::SerializationContext.url_helpers.respond_to? :url_for
- end
-
- test 'default_url_options return a Hash' do
- assert Hash, ActiveModelSerializers::SerializationContext.default_url_options.class
- end
- end
-end
diff --git a/test/active_model_serializers/test/schema_test.rb b/test/active_model_serializers/test/schema_test.rb
deleted file mode 100644
index 0fe497d7..00000000
--- a/test/active_model_serializers/test/schema_test.rb
+++ /dev/null
@@ -1,131 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Test
- class SchemaTest < ActionController::TestCase
- include ActiveModelSerializers::Test::Schema
-
- class MyController < ActionController::Base
- def index
- render json: profile
- end
-
- def show
- index
- end
-
- def name_as_a_integer
- profile.name = 1
- index
- end
-
- def render_using_json_api
- render json: profile, adapter: :json_api
- end
-
- def invalid_json_body
- render json: ''
- end
-
- private
-
- def profile
- @profile ||= Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- end
- end
-
- tests MyController
-
- def test_that_assert_with_a_valid_schema
- get :index
- assert_response_schema
- end
-
- def test_that_raises_a_minitest_error_with_a_invalid_schema
- message = "#/name: failed schema #/properties/name: For 'properties/name', \"Name 1\" is not an integer. and #/description: failed schema #/properties/description: For 'properties/description', \"Description 1\" is not a boolean."
-
- get :show
-
- error = assert_raises Minitest::Assertion do
- assert_response_schema
- end
- assert_equal(message, error.message)
- end
-
- def test_that_raises_error_with_a_custom_message_with_a_invalid_schema
- message = 'oh boy the show is broken'
- exception_message = "#/name: failed schema #/properties/name: For 'properties/name', \"Name 1\" is not an integer. and #/description: failed schema #/properties/description: For 'properties/description', \"Description 1\" is not a boolean."
- expected_message = "#{message}: #{exception_message}"
-
- get :show
-
- error = assert_raises Minitest::Assertion do
- assert_response_schema(nil, message)
- end
- assert_equal(expected_message, error.message)
- end
-
- def test_that_assert_with_a_custom_schema
- get :show
- assert_response_schema('custom/show.json')
- end
-
- def test_that_assert_with_a_hyper_schema
- get :show
- assert_response_schema('hyper_schema.json')
- end
-
- def test_simple_json_pointers
- get :show
- assert_response_schema('simple_json_pointers.json')
- end
-
- def test_simple_json_pointers_that_doesnt_match
- get :name_as_a_integer
-
- assert_raises Minitest::Assertion do
- assert_response_schema('simple_json_pointers.json')
- end
- end
-
- def test_json_api_schema
- get :render_using_json_api
- assert_response_schema('render_using_json_api.json')
- end
-
- def test_that_assert_with_a_custom_schema_directory
- original_schema_path = ActiveModelSerializers.config.schema_path
- ActiveModelSerializers.config.schema_path = 'test/support/custom_schemas'
-
- get :index
- assert_response_schema
-
- ActiveModelSerializers.config.schema_path = original_schema_path
- end
-
- def test_with_a_non_existent_file
- message = 'No Schema file at test/support/schemas/non-existent.json'
-
- get :show
-
- error = assert_raises ActiveModelSerializers::Test::Schema::MissingSchema do
- assert_response_schema('non-existent.json')
- end
- assert_equal(message, error.message)
- end
-
- def test_that_raises_with_a_invalid_json_body
- # message changes from JSON gem 2.0.2 to 2.2.0
- message = /A JSON text must at least contain two octets!|unexpected token at ''/
-
- get :invalid_json_body
-
- error = assert_raises ActiveModelSerializers::Test::Schema::InvalidSchemaError do
- assert_response_schema('custom/show.json')
- end
-
- assert_match(message, error.message)
- end
- end
- end
-end
diff --git a/test/active_model_serializers/test/serializer_test.rb b/test/active_model_serializers/test/serializer_test.rb
deleted file mode 100644
index 38dc60ba..00000000
--- a/test/active_model_serializers/test/serializer_test.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Test
- class SerializerTest < ActionController::TestCase
- include ActiveModelSerializers::Test::Serializer
-
- class MyController < ActionController::Base
- def render_using_serializer
- render json: Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- end
-
- def render_some_text
- render(plain: 'ok')
- end
- end
-
- tests MyController
-
- def test_supports_specifying_serializers_with_a_serializer_class
- get :render_using_serializer
- assert_serializer ProfileSerializer
- end
-
- def test_supports_specifying_serializers_with_a_regexp
- get :render_using_serializer
- assert_serializer(/\AProfile.+\Z/)
- end
-
- def test_supports_specifying_serializers_with_a_string
- get :render_using_serializer
- assert_serializer 'ProfileSerializer'
- end
-
- def test_supports_specifying_serializers_with_a_symbol
- get :render_using_serializer
- assert_serializer :profile_serializer
- end
-
- def test_supports_specifying_serializers_with_a_nil
- get :render_some_text
- assert_serializer nil
- end
-
- def test_raises_descriptive_error_message_when_serializer_was_not_rendered
- get :render_using_serializer
- e = assert_raise ActiveSupport::TestCase::Assertion do
- assert_serializer 'PostSerializer'
- end
- assert_match 'expecting <"PostSerializer"> but rendering with <["ProfileSerializer"]>', e.message
- end
-
- def test_raises_argument_error_when_asserting_with_invalid_object
- get :render_using_serializer
- e = assert_raise ArgumentError do
- assert_serializer Hash
- end
- assert_match 'assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil', e.message
- end
- end
- end
-end
diff --git a/test/active_record_test.rb b/test/active_record_test.rb
deleted file mode 100644
index 5bb941a4..00000000
--- a/test/active_record_test.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'test_helper'
-
-class ActiveRecordTest < ActiveSupport::TestCase
- include ActiveModel::Serializer::Lint::Tests
-
- def setup
- @resource = ARModels::Post.new
- end
-end
diff --git a/test/adapter/attributes_test.rb b/test/adapter/attributes_test.rb
deleted file mode 100644
index e60019f5..00000000
--- a/test/adapter/attributes_test.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class AttributesTest < ActiveSupport::TestCase
- class Person < ActiveModelSerializers::Model
- attributes :first_name, :last_name
- end
-
- class PersonSerializer < ActiveModel::Serializer
- attributes :first_name, :last_name
- end
-
- def setup
- ActionController::Base.cache_store.clear
- end
-
- def test_serializable_hash
- person = Person.new(first_name: 'Arthur', last_name: 'Dent')
- serializer = PersonSerializer.new(person)
- adapter = ActiveModelSerializers::Adapter::Attributes.new(serializer)
-
- assert_equal({ first_name: 'Arthur', last_name: 'Dent' },
- adapter.serializable_hash)
- end
-
- def test_serializable_hash_with_transform_key_casing
- person = Person.new(first_name: 'Arthur', last_name: 'Dent')
- serializer = PersonSerializer.new(person)
- adapter = ActiveModelSerializers::Adapter::Attributes.new(
- serializer,
- key_transform: :camel_lower
- )
-
- assert_equal({ firstName: 'Arthur', lastName: 'Dent' },
- adapter.serializable_hash)
- end
- end
- end
-end
diff --git a/test/adapter/deprecation_test.rb b/test/adapter/deprecation_test.rb
deleted file mode 100644
index ea858caa..00000000
--- a/test/adapter/deprecation_test.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-require 'test_helper'
-module ActiveModel
- class Serializer
- module Adapter
- class DeprecationTest < ActiveSupport::TestCase
- class PostSerializer < ActiveModel::Serializer
- attribute :body
- end
- setup do
- post = Post.new(id: 1, body: 'Hello')
- @serializer = PostSerializer.new(post)
- end
-
- def test_null_adapter_serialization_deprecation
- expected = {}
- assert_deprecated do
- assert_equal(expected, Null.new(@serializer).as_json)
- end
- end
-
- def test_json_adapter_serialization_deprecation
- expected = { post: { body: 'Hello' } }
- assert_deprecated do
- assert_equal(expected, Json.new(@serializer).as_json)
- end
- end
-
- def test_jsonapi_adapter_serialization_deprecation
- expected = {
- data: {
- id: '1',
- type: 'posts',
- attributes: {
- body: 'Hello'
- }
- }
- }
- assert_deprecated do
- assert_equal(expected, JsonApi.new(@serializer).as_json)
- end
- end
-
- def test_attributes_adapter_serialization_deprecation
- expected = { body: 'Hello' }
- assert_deprecated do
- assert_equal(expected, Attributes.new(@serializer).as_json)
- end
- end
-
- def test_adapter_create_deprecation
- assert_deprecated do
- Adapter.create(@serializer)
- end
- end
-
- def test_adapter_adapter_map_deprecation
- assert_deprecated do
- Adapter.adapter_map
- end
- end
-
- def test_adapter_adapters_deprecation
- assert_deprecated do
- Adapter.adapters
- end
- end
-
- def test_adapter_adapter_class_deprecation
- assert_deprecated do
- Adapter.adapter_class(:json_api)
- end
- end
-
- def test_adapter_register_deprecation
- assert_deprecated do
- begin
- Adapter.register(:test, Class.new)
- ensure
- Adapter.adapter_map.delete('test')
- end
- end
- end
-
- def test_adapter_lookup_deprecation
- assert_deprecated do
- Adapter.lookup(:json_api)
- end
- end
-
- private
-
- def assert_deprecated
- assert_output(nil, /deprecated/) do
- yield
- end
- end
- end
- end
- end
-end
diff --git a/test/adapter/json/belongs_to_test.rb b/test/adapter/json/belongs_to_test.rb
deleted file mode 100644
index 0f096f0b..00000000
--- a/test/adapter/json/belongs_to_test.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class Json
- class BelongsToTest < ActiveSupport::TestCase
- def setup
- @post = Post.new(id: 42, title: 'New Post', body: 'Body')
- @anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
- @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @post.comments = [@comment]
- @anonymous_post.comments = []
- @comment.post = @post
- @comment.author = nil
- @anonymous_post.author = nil
- @blog = Blog.new(id: 1, name: 'My Blog!!')
- @post.blog = @blog
- @anonymous_post.blog = nil
-
- @serializer = CommentSerializer.new(@comment)
- @adapter = ActiveModelSerializers::Adapter::Json.new(@serializer)
- ActionController::Base.cache_store.clear
- end
-
- def test_includes_post
- assert_equal({ id: 42, title: 'New Post', body: 'Body' }, @adapter.serializable_hash[:comment][:post])
- end
-
- def test_include_nil_author
- serializer = PostSerializer.new(@anonymous_post)
- adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
-
- assert_equal({ post: { title: 'Hello!!', body: 'Hello, world!!', id: 43, comments: [], blog: { id: 999, name: 'Custom blog' }, author: nil } }, adapter.serializable_hash)
- end
-
- def test_include_nil_author_with_specified_serializer
- serializer = PostPreviewSerializer.new(@anonymous_post)
- adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
-
- assert_equal({ post: { title: 'Hello!!', body: 'Hello, world!!', id: 43, comments: [], author: nil } }, adapter.serializable_hash)
- end
- end
- end
- end
-end
diff --git a/test/adapter/json/collection_test.rb b/test/adapter/json/collection_test.rb
deleted file mode 100644
index 8deb4050..00000000
--- a/test/adapter/json/collection_test.rb
+++ /dev/null
@@ -1,104 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class Json
- class Collection < ActiveSupport::TestCase
- def setup
- @author = Author.new(id: 1, name: 'Steve K.')
- @first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
- @second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
- @first_post.comments = []
- @second_post.comments = []
- @first_post.author = @author
- @second_post.author = @author
- @blog = Blog.new(id: 1, name: 'My Blog!!')
- @first_post.blog = @blog
- @second_post.blog = nil
-
- ActionController::Base.cache_store.clear
- end
-
- def test_with_serializer_option
- @blog.special_attribute = 'Special'
- @blog.articles = [@first_post, @second_post]
- serializer = ActiveModel::Serializer::CollectionSerializer.new([@blog], serializer: CustomBlogSerializer)
- adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
-
- expected = { blogs: [{
- id: 1,
- special_attribute: 'Special',
- articles: [{ id: 1, title: 'Hello!!', body: 'Hello, world!!' }, { id: 2, title: 'New Post', body: 'Body' }]
- }] }
- assert_equal expected, adapter.serializable_hash
- end
-
- def test_include_multiple_posts
- serializer = ActiveModel::Serializer::CollectionSerializer.new([@first_post, @second_post])
- adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
-
- expected = { posts: [{
- title: 'Hello!!',
- body: 'Hello, world!!',
- id: 1,
- comments: [],
- author: {
- id: 1,
- name: 'Steve K.'
- },
- blog: {
- id: 999,
- name: 'Custom blog'
- }
- }, {
- title: 'New Post',
- body: 'Body',
- id: 2,
- comments: [],
- author: {
- id: 1,
- name: 'Steve K.'
- },
- blog: {
- id: 999,
- name: 'Custom blog'
- }
- }] }
- assert_equal expected, adapter.serializable_hash
- end
-
- def test_root_is_underscored
- virtual_value = VirtualValue.new(id: 1)
- serializer = ActiveModel::Serializer::CollectionSerializer.new([virtual_value])
- adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
-
- assert_equal 1, adapter.serializable_hash[:virtual_values].length
- end
-
- def test_include_option
- serializer = ActiveModel::Serializer::CollectionSerializer.new([@first_post, @second_post])
- adapter = ActiveModelSerializers::Adapter::Json.new(serializer, include: '')
- actual = adapter.serializable_hash
- expected = { posts: [{ id: 1, title: 'Hello!!', body: 'Hello, world!!' },
- { id: 2, title: 'New Post', body: 'Body' }] }
-
- assert_equal(expected, actual)
- end
-
- def test_fields_with_no_associations_include_option
- actual = ActiveModelSerializers::SerializableResource.new(
- [@first_post, @second_post], adapter: :json, fields: [:id], include: []
- ).as_json
-
- expected = { posts: [{
- id: 1
- }, {
- id: 2
- }] }
-
- assert_equal(expected, actual)
- end
- end
- end
- end
-end
diff --git a/test/adapter/json/has_many_test.rb b/test/adapter/json/has_many_test.rb
deleted file mode 100644
index feeec93c..00000000
--- a/test/adapter/json/has_many_test.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class Json
- class HasManyTestTest < ActiveSupport::TestCase
- class ModelWithoutSerializer < ::Model
- attributes :id, :name
- end
-
- def setup
- ActionController::Base.cache_store.clear
- @author = Author.new(id: 1, name: 'Steve K.')
- @post = Post.new(id: 42, title: 'New Post', body: 'Body')
- @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
- @post.comments = [@first_comment, @second_comment]
- @post.author = @author
- @first_comment.post = @post
- @second_comment.post = @post
- @blog = Blog.new(id: 1, name: 'My Blog!!')
- @post.blog = @blog
- @tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
- @post.tags = [@tag]
- end
-
- def test_has_many
- serializer = PostSerializer.new(@post)
- adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
- assert_equal([
- { id: 1, body: 'ZOMG A COMMENT' },
- { id: 2, body: 'ZOMG ANOTHER COMMENT' }
- ], adapter.serializable_hash[:post][:comments])
- end
-
- def test_has_many_with_no_serializer
- post_serializer_class = Class.new(ActiveModel::Serializer) do
- attributes :id
- has_many :tags
- end
- serializer = post_serializer_class.new(@post)
- adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
- assert_equal({
- id: 42,
- tags: [
- { 'id' => 1, 'name' => '#hash_tag' }
- ]
- }.to_json, adapter.serializable_hash[:post].to_json)
- end
- end
- end
- end
-end
diff --git a/test/adapter/json/transform_test.rb b/test/adapter/json/transform_test.rb
deleted file mode 100644
index c102b5af..00000000
--- a/test/adapter/json/transform_test.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class Json
- class KeyCaseTest < ActiveSupport::TestCase
- def mock_request(key_transform = nil)
- context = Minitest::Mock.new
- context.expect(:request_url, URI)
- context.expect(:query_parameters, {})
- options = {}
- options[:key_transform] = key_transform if key_transform
- options[:serialization_context] = context
- serializer = CustomBlogSerializer.new(@blog)
- @adapter = ActiveModelSerializers::Adapter::Json.new(serializer, options)
- end
-
- class Post < ::Model; end
- class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body, :publish_at
- end
-
- setup do
- ActionController::Base.cache_store.clear
- @blog = Blog.new(id: 1, name: 'My Blog!!', special_attribute: 'neat')
- end
-
- def test_transform_default
- mock_request
- assert_equal({
- blog: { id: 1, special_attribute: 'neat', articles: nil }
- }, @adapter.serializable_hash)
- end
-
- def test_transform_global_config
- mock_request
- result = with_config(key_transform: :camel_lower) do
- @adapter.serializable_hash
- end
- assert_equal({
- blog: { id: 1, specialAttribute: 'neat', articles: nil }
- }, result)
- end
-
- def test_transform_serialization_ctx_overrides_global_config
- mock_request(:camel)
- result = with_config(key_transform: :camel_lower) do
- @adapter.serializable_hash
- end
- assert_equal({
- Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
- }, result)
- end
-
- def test_transform_undefined
- mock_request(:blam)
- result = nil
- assert_raises NoMethodError do
- result = @adapter.serializable_hash
- end
- end
-
- def test_transform_dash
- mock_request(:dash)
- assert_equal({
- blog: { id: 1, :"special-attribute" => 'neat', articles: nil }
- }, @adapter.serializable_hash)
- end
-
- def test_transform_unaltered
- mock_request(:unaltered)
- assert_equal({
- blog: { id: 1, special_attribute: 'neat', articles: nil }
- }, @adapter.serializable_hash)
- end
-
- def test_transform_camel
- mock_request(:camel)
- assert_equal({
- Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
- }, @adapter.serializable_hash)
- end
-
- def test_transform_camel_lower
- mock_request(:camel_lower)
- assert_equal({
- blog: { id: 1, specialAttribute: 'neat', articles: nil }
- }, @adapter.serializable_hash)
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/belongs_to_test.rb b/test/adapter/json_api/belongs_to_test.rb
deleted file mode 100644
index ded83ab5..00000000
--- a/test/adapter/json_api/belongs_to_test.rb
+++ /dev/null
@@ -1,155 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class BelongsToTest < ActiveSupport::TestCase
- def setup
- @author = Author.new(id: 1, name: 'Steve K.')
- @author.bio = nil
- @author.roles = []
- @blog = Blog.new(id: 23, name: 'AMS Blog')
- @post = Post.new(id: 42, title: 'New Post', body: 'Body')
- @anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
- @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @post.comments = [@comment]
- @post.blog = @blog
- @anonymous_post.comments = []
- @anonymous_post.blog = nil
- @comment.post = @post
- @comment.author = nil
- @post.author = @author
- @anonymous_post.author = nil
- @blog = Blog.new(id: 1, name: 'My Blog!!')
- @blog.writer = @author
- @blog.articles = [@post, @anonymous_post]
- @author.posts = []
-
- @serializer = CommentSerializer.new(@comment)
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
- ActionController::Base.cache_store.clear
- end
-
- def test_includes_post_id
- expected = { data: { type: 'posts', id: '42' } }
-
- assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:post])
- end
-
- def test_includes_linked_post
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:post])
- expected = [{
- id: '42',
- type: 'posts',
- attributes: {
- title: 'New Post',
- body: 'Body'
- },
- relationships: {
- comments: { data: [{ type: 'comments', id: '1' }] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: { type: 'authors', id: '1' } }
- }
- }]
- assert_equal expected, @adapter.serializable_hash[:included]
- end
-
- def test_limiting_linked_post_fields
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:post], fields: { post: [:title, :comments, :blog, :author] })
- expected = [{
- id: '42',
- type: 'posts',
- attributes: {
- title: 'New Post'
- },
- relationships: {
- comments: { data: [{ type: 'comments', id: '1' }] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: { type: 'authors', id: '1' } }
- }
- }]
- assert_equal expected, @adapter.serializable_hash[:included]
- end
-
- def test_include_nil_author
- serializer = PostSerializer.new(@anonymous_post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
-
- assert_equal({ comments: { data: [] }, blog: { data: { type: 'blogs', id: '999' } }, author: { data: nil } }, adapter.serializable_hash[:data][:relationships])
- end
-
- def test_include_type_for_association_when_different_than_name
- serializer = BlogSerializer.new(@blog)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
- relationships = adapter.serializable_hash[:data][:relationships]
- expected = {
- writer: {
- data: {
- type: 'authors',
- id: '1'
- }
- },
- articles: {
- data: [
- {
- type: 'posts',
- id: '42'
- },
- {
- type: 'posts',
- id: '43'
- }
- ]
- }
- }
- assert_equal expected, relationships
- end
-
- def test_include_linked_resources_with_type_name
- serializer = BlogSerializer.new(@blog)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, include: [:writer, :articles])
- linked = adapter.serializable_hash[:included]
- expected = [
- {
- id: '1',
- type: 'authors',
- attributes: {
- name: 'Steve K.'
- },
- relationships: {
- posts: { data: [] },
- roles: { data: [] },
- bio: { data: nil }
- }
- }, {
- id: '42',
- type: 'posts',
- attributes: {
- title: 'New Post',
- body: 'Body'
- },
- relationships: {
- comments: { data: [{ type: 'comments', id: '1' }] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: { type: 'authors', id: '1' } }
- }
- }, {
- id: '43',
- type: 'posts',
- attributes: {
- title: 'Hello!!',
- body: 'Hello, world!!'
- },
- relationships: {
- comments: { data: [] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: nil }
- }
- }
- ]
- assert_equal expected, linked
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/collection_test.rb b/test/adapter/json_api/collection_test.rb
deleted file mode 100644
index e60a824e..00000000
--- a/test/adapter/json_api/collection_test.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class CollectionTest < ActiveSupport::TestCase
- def setup
- @author = Author.new(id: 1, name: 'Steve K.')
- @author.bio = nil
- @blog = Blog.new(id: 23, name: 'AMS Blog')
- @first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
- @second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
- @first_post.comments = []
- @second_post.comments = []
- @first_post.blog = @blog
- @second_post.blog = nil
- @first_post.author = @author
- @second_post.author = @author
- @author.posts = [@first_post, @second_post]
-
- @serializer = ActiveModel::Serializer::CollectionSerializer.new([@first_post, @second_post])
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
- ActionController::Base.cache_store.clear
- end
-
- def test_include_multiple_posts
- expected = [
- {
- id: '1',
- type: 'posts',
- attributes: {
- title: 'Hello!!',
- body: 'Hello, world!!'
- },
- relationships: {
- comments: { data: [] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: { type: 'authors', id: '1' } }
- }
- },
- {
- id: '2',
- type: 'posts',
- attributes: {
- title: 'New Post',
- body: 'Body'
- },
- relationships: {
- comments: { data: [] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: { type: 'authors', id: '1' } }
- }
- }
- ]
-
- assert_equal(expected, @adapter.serializable_hash[:data])
- end
-
- def test_limiting_fields
- actual = ActiveModelSerializers::SerializableResource.new(
- [@first_post, @second_post],
- adapter: :json_api,
- fields: { posts: %w(title comments blog author) }
- ).serializable_hash
- expected = [
- {
- id: '1',
- type: 'posts',
- attributes: {
- title: 'Hello!!'
- },
- relationships: {
- comments: { data: [] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: { type: 'authors', id: '1' } }
- }
- },
- {
- id: '2',
- type: 'posts',
- attributes: {
- title: 'New Post'
- },
- relationships: {
- comments: { data: [] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: { type: 'authors', id: '1' } }
- }
- }
- ]
- assert_equal(expected, actual[:data])
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/errors_test.rb b/test/adapter/json_api/errors_test.rb
deleted file mode 100644
index cae7a5a6..00000000
--- a/test/adapter/json_api/errors_test.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi < Base
- class ErrorsTest < Minitest::Test
- include ActiveModel::Serializer::Lint::Tests
-
- def setup
- @resource = ModelWithErrors.new
- end
-
- def test_active_model_with_error
- options = {
- serializer: ActiveModel::Serializer::ErrorSerializer,
- adapter: :json_api
- }
-
- @resource.errors.add(:name, 'cannot be nil')
-
- serializable_resource = ActiveModelSerializers::SerializableResource.new(@resource, options)
- assert_equal serializable_resource.serializer_instance.attributes, {}
- assert_equal serializable_resource.serializer_instance.object, @resource
-
- expected_errors_object = {
- errors: [
- {
- source: { pointer: '/data/attributes/name' },
- detail: 'cannot be nil'
- }
- ]
- }
- assert_equal serializable_resource.as_json, expected_errors_object
- end
-
- def test_active_model_with_multiple_errors
- options = {
- serializer: ActiveModel::Serializer::ErrorSerializer,
- adapter: :json_api
- }
-
- @resource.errors.add(:name, 'cannot be nil')
- @resource.errors.add(:name, 'must be longer')
- @resource.errors.add(:id, 'must be a uuid')
-
- serializable_resource = ActiveModelSerializers::SerializableResource.new(@resource, options)
- assert_equal serializable_resource.serializer_instance.attributes, {}
- assert_equal serializable_resource.serializer_instance.object, @resource
-
- expected_errors_object = {
- errors: [
- { source: { pointer: '/data/attributes/name' }, detail: 'cannot be nil' },
- { source: { pointer: '/data/attributes/name' }, detail: 'must be longer' },
- { source: { pointer: '/data/attributes/id' }, detail: 'must be a uuid' }
- ]
- }
- assert_equal serializable_resource.as_json, expected_errors_object
- end
-
- # see http://jsonapi.org/examples/
- def test_parameter_source_type_error
- parameter = 'auther'
- error_source = ActiveModelSerializers::Adapter::JsonApi::Error.error_source(:parameter, parameter)
- assert_equal({ parameter: parameter }, error_source)
- end
-
- def test_unknown_source_type_error
- value = 'auther'
- assert_raises(ActiveModelSerializers::Adapter::JsonApi::Error::UnknownSourceTypeError) do
- ActiveModelSerializers::Adapter::JsonApi::Error.error_source(:hyper, value)
- end
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/fields_test.rb b/test/adapter/json_api/fields_test.rb
deleted file mode 100644
index 85228318..00000000
--- a/test/adapter/json_api/fields_test.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- 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 :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
- type 'authors'
- attributes :name, :birthday
- end
-
- class CommentSerializer < ActiveModel::Serializer
- type 'comments'
- attributes :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 = { posts: [:title] }
- hash = serializable(@post, adapter: :json_api, fields: fields).serializable_hash
- expected = {
- title: 'Title 1'
- }
-
- assert_equal(expected, hash[:data][:attributes])
- end
-
- def test_fields_relationships
- fields = { posts: [:author] }
- hash = serializable(@post, adapter: :json_api, fields: fields).serializable_hash
- expected = {
- author: {
- data: {
- type: 'authors',
- id: '1'
- }
- }
- }
-
- assert_equal(expected, hash[:data][:relationships])
- end
-
- def test_fields_included
- fields = { posts: [:author], comments: [:body] }
- hash = serializable(@post, adapter: :json_api, fields: fields, include: 'comments').serializable_hash
- expected = [
- {
- type: 'comments',
- id: '7',
- attributes: {
- body: 'cool'
- }
- }, {
- type: 'comments',
- id: '12',
- attributes: {
- body: 'awesome'
- }
- }
- ]
-
- assert_equal(expected, hash[:included])
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/has_many_embed_ids_test.rb b/test/adapter/json_api/has_many_embed_ids_test.rb
deleted file mode 100644
index e016de28..00000000
--- a/test/adapter/json_api/has_many_embed_ids_test.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class HasManyEmbedIdsTest < ActiveSupport::TestCase
- def setup
- @author = Author.new(name: 'Steve K.')
- @author.bio = nil
- @author.roles = nil
- @first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
- @second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
- @author.posts = [@first_post, @second_post]
- @first_post.author = @author
- @second_post.author = @author
- @first_post.comments = []
- @second_post.comments = []
- @blog = Blog.new(id: 23, name: 'AMS Blog')
- @first_post.blog = @blog
- @second_post.blog = nil
-
- @serializer = AuthorSerializer.new(@author)
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
- end
-
- def test_includes_comment_ids
- expected = {
- data: [
- { type: 'posts', id: '1' },
- { type: 'posts', id: '2' }
- ]
- }
-
- assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:posts])
- end
-
- def test_no_includes_linked_comments
- assert_nil @adapter.serializable_hash[:linked]
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/has_many_explicit_serializer_test.rb b/test/adapter/json_api/has_many_explicit_serializer_test.rb
deleted file mode 100644
index f598bc9b..00000000
--- a/test/adapter/json_api/has_many_explicit_serializer_test.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- # Test 'has_many :assocs, serializer: AssocXSerializer'
- class HasManyExplicitSerializerTest < ActiveSupport::TestCase
- def setup
- @post = Post.new(title: 'New Post', body: 'Body')
- @author = Author.new(name: 'Jane Blogger')
- @author.posts = [@post]
- @post.author = @author
- @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
- @post.comments = [@first_comment, @second_comment]
- @first_comment.post = @post
- @first_comment.author = nil
- @second_comment.post = @post
- @second_comment.author = nil
- @blog = Blog.new(id: 23, name: 'AMS Blog')
- @post.blog = @blog
-
- @serializer = PostPreviewSerializer.new(@post)
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(
- @serializer,
- include: [:comments, :author]
- )
- end
-
- def test_includes_comment_ids
- expected = {
- data: [
- { type: 'comments', id: '1' },
- { type: 'comments', id: '2' }
- ]
- }
-
- assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments])
- end
-
- def test_includes_linked_data
- # If CommentPreviewSerializer is applied correctly the body text will not be present in the output
- expected = [
- {
- id: '1',
- type: 'comments',
- relationships: {
- post: { data: { type: 'posts', id: @post.id.to_s } }
- }
- },
- {
- id: '2',
- type: 'comments',
- relationships: {
- post: { data: { type: 'posts', id: @post.id.to_s } }
- }
- },
- {
- id: @author.id.to_s,
- type: 'authors',
- relationships: {
- posts: { data: [{ type: 'posts', id: @post.id.to_s }] }
- }
- }
- ]
-
- assert_equal(expected, @adapter.serializable_hash[:included])
- end
-
- def test_includes_author_id
- expected = {
- data: { type: 'authors', id: @author.id.to_s }
- }
-
- assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:author])
- end
-
- def test_explicit_serializer_with_null_resource
- @post.author = nil
-
- expected = { data: nil }
-
- assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:author])
- end
-
- def test_explicit_serializer_with_null_collection
- @post.comments = []
-
- expected = { data: [] }
-
- assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments])
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/has_many_test.rb b/test/adapter/json_api/has_many_test.rb
deleted file mode 100644
index a9fa9ac9..00000000
--- a/test/adapter/json_api/has_many_test.rb
+++ /dev/null
@@ -1,173 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class HasManyTest < ActiveSupport::TestCase
- class ModelWithoutSerializer < ::Model
- attributes :id, :name
- end
-
- def setup
- ActionController::Base.cache_store.clear
- @author = Author.new(id: 1, name: 'Steve K.')
- @author.posts = []
- @author.bio = nil
- @post = Post.new(id: 1, title: 'New Post', body: 'Body')
- @post_without_comments = Post.new(id: 2, title: 'Second Post', body: 'Second')
- @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @first_comment.author = nil
- @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
- @second_comment.author = nil
- @post.comments = [@first_comment, @second_comment]
- @post_without_comments.comments = []
- @first_comment.post = @post
- @second_comment.post = @post
- @post.author = @author
- @post_without_comments.author = nil
- @blog = Blog.new(id: 1, name: 'My Blog!!')
- @blog.writer = @author
- @blog.articles = [@post]
- @post.blog = @blog
- @post_without_comments.blog = nil
- @tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
- @post.tags = [@tag]
- @serializer = PostSerializer.new(@post)
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
-
- @virtual_value = VirtualValue.new(id: 1)
- end
-
- def test_includes_comment_ids
- expected = { data: [{ type: 'comments', id: '1' }, { type: 'comments', id: '2' }] }
-
- assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments])
- end
-
- test 'relationships can be whitelisted via fields' do
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, fields: { posts: [:author] })
- result = @adapter.serializable_hash
- expected = {
- data: {
- id: '1',
- type: 'posts',
- relationships: {
- author: {
- data: {
- id: '1',
- type: 'authors'
- }
- }
- }
- }
- }
-
- assert_equal expected, result
- end
-
- def test_includes_linked_comments
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:comments])
- expected = [{
- id: '1',
- type: 'comments',
- attributes: {
- body: 'ZOMG A COMMENT'
- },
- relationships: {
- post: { data: { type: 'posts', id: '1' } },
- author: { data: nil }
- }
- }, {
- id: '2',
- type: 'comments',
- attributes: {
- body: 'ZOMG ANOTHER COMMENT'
- },
- relationships: {
- post: { data: { type: 'posts', id: '1' } },
- author: { data: nil }
- }
- }]
- assert_equal expected, @adapter.serializable_hash[:included]
- end
-
- def test_limit_fields_of_linked_comments
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:comments], fields: { comment: [:id, :post, :author] })
- expected = [{
- id: '1',
- type: 'comments',
- relationships: {
- post: { data: { type: 'posts', id: '1' } },
- author: { data: nil }
- }
- }, {
- id: '2',
- type: 'comments',
- relationships: {
- post: { data: { type: 'posts', id: '1' } },
- author: { data: nil }
- }
- }]
- assert_equal expected, @adapter.serializable_hash[:included]
- end
-
- def test_no_include_linked_if_comments_is_empty
- serializer = PostSerializer.new(@post_without_comments)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
-
- assert_nil adapter.serializable_hash[:linked]
- end
-
- def test_include_type_for_association_when_different_than_name
- serializer = BlogSerializer.new(@blog)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
- actual = adapter.serializable_hash[:data][:relationships][:articles]
-
- expected = {
- data: [{
- type: 'posts',
- id: '1'
- }]
- }
- assert_equal expected, actual
- end
-
- def test_has_many_with_no_serializer
- post_serializer_class = Class.new(ActiveModel::Serializer) do
- attributes :id
- has_many :tags
- end
- serializer = post_serializer_class.new(@post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
-
- assert_equal({
- data: {
- id: '1',
- type: 'posts',
- relationships: {
- tags: { data: [@tag.as_json] }
- }
- }
- }, adapter.serializable_hash)
- end
-
- def test_has_many_with_virtual_value
- serializer = VirtualValueSerializer.new(@virtual_value)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
-
- assert_equal({
- data: {
- id: '1',
- type: 'virtual-values',
- relationships: {
- maker: { data: { type: 'makers', id: '1' } },
- reviews: { data: [{ type: 'reviews', id: '1' },
- { type: 'reviews', id: '2' }] }
- }
- }
- }, adapter.serializable_hash)
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/has_one_test.rb b/test/adapter/json_api/has_one_test.rb
deleted file mode 100644
index eb505a0d..00000000
--- a/test/adapter/json_api/has_one_test.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class HasOneTest < ActiveSupport::TestCase
- def setup
- @author = Author.new(id: 1, name: 'Steve K.')
- @bio = Bio.new(id: 43, content: 'AMS Contributor')
- @author.bio = @bio
- @bio.author = @author
- @post = Post.new(id: 42, title: 'New Post', body: 'Body')
- @anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
- @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @post.comments = [@comment]
- @anonymous_post.comments = []
- @comment.post = @post
- @comment.author = nil
- @post.author = @author
- @anonymous_post.author = nil
- @blog = Blog.new(id: 1, name: 'My Blog!!')
- @blog.writer = @author
- @blog.articles = [@post, @anonymous_post]
- @author.posts = []
- @author.roles = []
-
- @virtual_value = VirtualValue.new(id: 1)
-
- @serializer = AuthorSerializer.new(@author)
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:bio, :posts])
- end
-
- def test_includes_bio_id
- expected = { data: { type: 'bios', id: '43' } }
-
- assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:bio])
- end
-
- def test_includes_linked_bio
- @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:bio])
-
- expected = [
- {
- id: '43',
- type: 'bios',
- attributes: {
- content: 'AMS Contributor',
- rating: nil
- },
- relationships: {
- author: { data: { type: 'authors', id: '1' } }
- }
- }
- ]
-
- assert_equal(expected, @adapter.serializable_hash[:included])
- end
-
- def test_has_one_with_virtual_value
- serializer = VirtualValueSerializer.new(@virtual_value)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
-
- expected = {
- data: {
- id: '1',
- type: 'virtual-values',
- relationships: {
- maker: { data: { type: 'makers', id: '1' } },
- reviews: { data: [{ type: 'reviews', id: '1' },
- { type: 'reviews', id: '2' }] }
- }
- }
- }
-
- assert_equal(expected, adapter.serializable_hash)
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/include_data_if_sideloaded_test.rb b/test/adapter/json_api/include_data_if_sideloaded_test.rb
deleted file mode 100644
index c0da9488..00000000
--- a/test/adapter/json_api/include_data_if_sideloaded_test.rb
+++ /dev/null
@@ -1,183 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- module Adapter
- class JsonApi
- class IncludeParamTest < ActiveSupport::TestCase
- IncludeParamAuthor = Class.new(::Model) do
- associations :tags, :posts
- end
-
- class CustomCommentLoader
- def all
- [{ foo: 'bar' }]
- end
- end
- class Tag < ::Model
- attributes :id, :name
- end
-
- class TagSerializer < ActiveModel::Serializer
- type 'tags'
- attributes :id, :name
- end
-
- class PostWithTagsSerializer < ActiveModel::Serializer
- type 'posts'
- attributes :id
- has_many :tags
- end
-
- class IncludeParamAuthorSerializer < ActiveModel::Serializer
- class_attribute :comment_loader
-
- has_many :tags, serializer: TagSerializer do
- link :self, '//example.com/link_author/relationships/tags'
- include_data :if_sideloaded
- end
-
- has_many :unlinked_tags, serializer: TagSerializer do
- include_data :if_sideloaded
- end
-
- has_many :posts, serializer: PostWithTagsSerializer do
- include_data :if_sideloaded
- end
- has_many :locations do
- include_data :if_sideloaded
- end
- has_many :comments do
- include_data :if_sideloaded
- IncludeParamAuthorSerializer.comment_loader.all
- end
- end
-
- def setup
- IncludeParamAuthorSerializer.comment_loader = Class.new(CustomCommentLoader).new
- @tag = Tag.new(id: 1337, name: 'mytag')
- @author = IncludeParamAuthor.new(
- id: 1337,
- tags: [@tag]
- )
- end
-
- def test_relationship_not_loaded_when_not_included
- expected = {
- links: {
- self: '//example.com/link_author/relationships/tags'
- }
- }
-
- @author.define_singleton_method(:read_attribute_for_serialization) do |attr|
- fail 'should not be called' if attr == :tags
- super(attr)
- end
-
- assert_relationship(:tags, expected)
- end
-
- def test_relationship_included
- expected = {
- data: [
- {
- id: '1337',
- type: 'tags'
- }
- ],
- links: {
- self: '//example.com/link_author/relationships/tags'
- }
- }
-
- assert_relationship(:tags, expected, include: :tags)
- end
-
- def test_sideloads_included
- expected = [
- {
- id: '1337',
- type: 'tags',
- attributes: { name: 'mytag' }
- }
- ]
- hash = result(include: :tags)
- assert_equal(expected, hash[:included])
- end
-
- def test_nested_relationship
- expected = {
- data: [
- {
- id: '1337',
- type: 'tags'
- }
- ],
- links: {
- self: '//example.com/link_author/relationships/tags'
- }
- }
-
- expected_no_data = {
- links: {
- self: '//example.com/link_author/relationships/tags'
- }
- }
-
- assert_relationship(:tags, expected, include: [:tags, { posts: :tags }])
-
- @author.define_singleton_method(:read_attribute_for_serialization) do |attr|
- fail 'should not be called' if attr == :tags
- super(attr)
- end
-
- assert_relationship(:tags, expected_no_data, include: { posts: :tags })
- end
-
- def test_include_params_with_no_block
- @author.define_singleton_method(:read_attribute_for_serialization) do |attr|
- fail 'should not be called' if attr == :locations
- super(attr)
- end
-
- expected = { meta: {} }
-
- assert_relationship(:locations, expected)
- end
-
- def test_block_relationship
- expected = {
- data: [
- { 'foo' => 'bar' }
- ]
- }
-
- assert_relationship(:comments, expected, include: [:comments])
- end
-
- def test_node_not_included_when_no_link
- expected = { meta: {} }
- assert_relationship(:unlinked_tags, expected, key_transform: :unaltered)
- end
-
- private
-
- def assert_relationship(relationship_name, expected, opts = {})
- actual = relationship_data(relationship_name, opts)
- assert_equal(expected, actual)
- end
-
- def result(opts)
- opts = { adapter: :json_api }.merge(opts)
- serializable(@author, opts).serializable_hash
- end
-
- def relationship_data(relationship_name, opts = {})
- hash = result(opts)
- hash[:data][:relationships][relationship_name]
- end
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/json_api_test.rb b/test/adapter/json_api/json_api_test.rb
deleted file mode 100644
index cb2ce909..00000000
--- a/test/adapter/json_api/json_api_test.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApiTest < ActiveSupport::TestCase
- def setup
- ActionController::Base.cache_store.clear
- @author = Author.new(id: 1, name: 'Steve K.')
- @post = Post.new(id: 1, title: 'New Post', body: 'Body')
- @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
- @post.comments = [@first_comment, @second_comment]
- @first_comment.post = @post
- @second_comment.post = @post
- @post.author = @author
- @blog = Blog.new(id: 1, name: 'My Blog!!')
- @post.blog = @blog
- end
-
- def test_custom_keys
- serializer = PostWithCustomKeysSerializer.new(@post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
-
- assert_equal({
- reviews: { data: [{ type: 'comments', id: '1' },
- { type: 'comments', id: '2' }] },
- writer: { data: { type: 'authors', id: '1' } },
- site: { data: { type: 'blogs', id: '1' } }
- }, adapter.serializable_hash[:data][:relationships])
- end
- end
- end
-end
diff --git a/test/adapter/json_api/linked_test.rb b/test/adapter/json_api/linked_test.rb
deleted file mode 100644
index 0d9c69b6..00000000
--- a/test/adapter/json_api/linked_test.rb
+++ /dev/null
@@ -1,413 +0,0 @@
-require 'test_helper'
-
-class NestedPost < ::Model; associations :nested_posts end
-class NestedPostSerializer < ActiveModel::Serializer
- has_many :nested_posts
-end
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class LinkedTest < ActiveSupport::TestCase
- def setup
- @author1 = Author.new(id: 1, name: 'Steve K.')
- @author2 = Author.new(id: 2, name: 'Tenderlove')
- @bio1 = Bio.new(id: 1, content: 'AMS Contributor')
- @bio2 = Bio.new(id: 2, content: 'Rails Contributor')
- @first_post = Post.new(id: 10, title: 'Hello!!', body: 'Hello, world!!')
- @second_post = Post.new(id: 20, title: 'New Post', body: 'Body')
- @third_post = Post.new(id: 30, title: 'Yet Another Post', body: 'Body')
- @blog = Blog.new(name: 'AMS Blog')
- @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
- @first_post.blog = @blog
- @second_post.blog = @blog
- @third_post.blog = nil
- @first_post.comments = [@first_comment, @second_comment]
- @second_post.comments = []
- @third_post.comments = []
- @first_post.author = @author1
- @second_post.author = @author2
- @third_post.author = @author1
- @first_comment.post = @first_post
- @first_comment.author = nil
- @second_comment.post = @first_post
- @second_comment.author = nil
- @author1.posts = [@first_post, @third_post]
- @author1.bio = @bio1
- @author1.roles = []
- @author2.posts = [@second_post]
- @author2.bio = @bio2
- @author2.roles = []
- @bio1.author = @author1
- @bio2.author = @author2
- end
-
- def test_include_multiple_posts_and_linked_array
- serializer = ActiveModel::Serializer::CollectionSerializer.new([@first_post, @second_post])
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(
- serializer,
- include: [:comments, author: [:bio]]
- )
- alt_adapter = ActiveModelSerializers::Adapter::JsonApi.new(
- serializer,
- include: [:comments, author: [:bio]]
- )
-
- expected = {
- data: [
- {
- id: '10',
- type: 'posts',
- attributes: {
- title: 'Hello!!',
- body: 'Hello, world!!'
- },
- relationships: {
- comments: { data: [{ type: 'comments', id: '1' }, { type: 'comments', id: '2' }] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: { type: 'authors', id: '1' } }
- }
- },
- {
- id: '20',
- type: 'posts',
- attributes: {
- title: 'New Post',
- body: 'Body'
- },
- relationships: {
- comments: { data: [] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: { type: 'authors', id: '2' } }
- }
- }
- ],
- included: [
- {
- id: '1',
- type: 'comments',
- attributes: {
- body: 'ZOMG A COMMENT'
- },
- relationships: {
- post: { data: { type: 'posts', id: '10' } },
- author: { data: nil }
- }
- }, {
- id: '2',
- type: 'comments',
- attributes: {
- body: 'ZOMG ANOTHER COMMENT'
- },
- relationships: {
- post: { data: { type: 'posts', id: '10' } },
- author: { data: nil }
- }
- }, {
- id: '1',
- type: 'authors',
- attributes: {
- name: 'Steve K.'
- },
- relationships: {
- posts: { data: [{ type: 'posts', id: '10' }, { type: 'posts', id: '30' }] },
- roles: { data: [] },
- bio: { data: { type: 'bios', id: '1' } }
- }
- }, {
- id: '1',
- type: 'bios',
- attributes: {
- content: 'AMS Contributor',
- rating: nil
- },
- relationships: {
- author: { data: { type: 'authors', id: '1' } }
- }
- }, {
- id: '2',
- type: 'authors',
- attributes: {
- name: 'Tenderlove'
- },
- relationships: {
- posts: { data: [{ type: 'posts', id: '20' }] },
- roles: { data: [] },
- bio: { data: { type: 'bios', id: '2' } }
- }
- }, {
- id: '2',
- type: 'bios',
- attributes: {
- rating: nil,
- content: 'Rails Contributor'
- },
- relationships: {
- author: { data: { type: 'authors', id: '2' } }
- }
- }
- ]
- }
- assert_equal expected, adapter.serializable_hash
- assert_equal expected, alt_adapter.serializable_hash
- end
-
- def test_include_multiple_posts_and_linked
- serializer = BioSerializer.new @bio1
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(
- serializer,
- include: [author: [:posts]]
- )
- alt_adapter = ActiveModelSerializers::Adapter::JsonApi.new(
- serializer,
- include: [author: [:posts]]
- )
-
- expected = [
- {
- id: '1',
- type: 'authors',
- attributes: {
- name: 'Steve K.'
- },
- relationships: {
- posts: { data: [{ type: 'posts', id: '10' }, { type: 'posts', id: '30' }] },
- roles: { data: [] },
- bio: { data: { type: 'bios', id: '1' } }
- }
- }, {
- id: '10',
- type: 'posts',
- attributes: {
- title: 'Hello!!',
- body: 'Hello, world!!'
- },
- relationships: {
- comments: { data: [{ type: 'comments', id: '1' }, { type: 'comments', id: '2' }] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: { type: 'authors', id: '1' } }
- }
- }, {
- id: '30',
- type: 'posts',
- attributes: {
- title: 'Yet Another Post',
- body: 'Body'
- },
- relationships: {
- comments: { data: [] },
- blog: { data: { type: 'blogs', id: '999' } },
- author: { data: { type: 'authors', id: '1' } }
- }
- }
- ]
-
- assert_equal expected, adapter.serializable_hash[:included]
- assert_equal expected, alt_adapter.serializable_hash[:included]
- end
-
- def test_underscore_model_namespace_for_linked_resource_type
- spammy_post = Post.new(id: 123)
- spammy_post.related = [Spam::UnrelatedLink.new(id: 456)]
- serializer = SpammyPostSerializer.new(spammy_post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
- relationships = adapter.serializable_hash[:data][:relationships]
- expected = {
- related: {
- data: [{
- type: 'spam-unrelated-links',
- id: '456'
- }]
- }
- }
- assert_equal expected, relationships
- end
-
- def test_underscore_model_namespace_with_namespace_separator_for_linked_resource_type
- spammy_post = Post.new(id: 123)
- spammy_post.related = [Spam::UnrelatedLink.new(id: 456)]
- serializer = SpammyPostSerializer.new(spammy_post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
- relationships = with_namespace_separator '--' do
- adapter.serializable_hash[:data][:relationships]
- end
- expected = {
- related: {
- data: [{
- type: 'spam--unrelated-links',
- id: '456'
- }]
- }
- }
- assert_equal expected, relationships
- end
-
- def test_multiple_references_to_same_resource
- serializer = ActiveModel::Serializer::CollectionSerializer.new([@first_comment, @second_comment])
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(
- serializer,
- include: [:post]
- )
-
- expected = [
- {
- id: '10',
- type: 'posts',
- attributes: {
- title: 'Hello!!',
- body: 'Hello, world!!'
- },
- relationships: {
- comments: {
- data: [{ type: 'comments', id: '1' }, { type: 'comments', id: '2' }]
- },
- blog: {
- data: { type: 'blogs', id: '999' }
- },
- author: {
- data: { type: 'authors', id: '1' }
- }
- }
- }
- ]
-
- assert_equal expected, adapter.serializable_hash[:included]
- end
-
- def test_nil_link_with_specified_serializer
- @first_post.author = nil
- serializer = PostPreviewSerializer.new(@first_post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(
- serializer,
- include: [:author]
- )
-
- expected = {
- data: {
- id: '10',
- type: 'posts',
- attributes: {
- title: 'Hello!!',
- body: 'Hello, world!!'
- },
- relationships: {
- comments: { data: [{ type: 'comments', id: '1' }, { type: 'comments', id: '2' }] },
- author: { data: nil }
- }
- }
- }
- assert_equal expected, adapter.serializable_hash
- end
- end
-
- class NoDuplicatesTest < ActiveSupport::TestCase
- class Post < ::Model; associations :author end
- class Author < ::Model; associations :posts, :roles, :bio end
-
- class PostSerializer < ActiveModel::Serializer
- type 'posts'
- belongs_to :author
- end
-
- class AuthorSerializer < ActiveModel::Serializer
- type 'authors'
- has_many :posts
- end
-
- def setup
- @author = Author.new(id: 1, posts: [], roles: [], bio: nil)
- @post1 = Post.new(id: 1, author: @author)
- @post2 = Post.new(id: 2, author: @author)
- @author.posts << @post1
- @author.posts << @post2
-
- @nestedpost1 = NestedPost.new(id: 1, nested_posts: [])
- @nestedpost2 = NestedPost.new(id: 2, nested_posts: [])
- @nestedpost1.nested_posts << @nestedpost1
- @nestedpost1.nested_posts << @nestedpost2
- @nestedpost2.nested_posts << @nestedpost1
- @nestedpost2.nested_posts << @nestedpost2
- end
-
- def test_no_duplicates
- hash = ActiveModelSerializers::SerializableResource.new(@post1, adapter: :json_api,
- include: '*.*')
- .serializable_hash
- expected = [
- {
- type: 'authors', id: '1',
- relationships: {
- posts: {
- data: [
- { type: 'posts', id: '1' },
- { type: 'posts', id: '2' }
- ]
- }
- }
- },
- {
- type: 'posts', id: '2',
- relationships: {
- author: {
- data: { type: 'authors', id: '1' }
- }
- }
- }
- ]
- assert_equal(expected, hash[:included])
- end
-
- def test_no_duplicates_collection
- hash = ActiveModelSerializers::SerializableResource.new(
- [@post1, @post2],
- adapter: :json_api,
- include: '*.*'
- ).serializable_hash
- expected = [
- {
- type: 'authors', id: '1',
- relationships: {
- posts: {
- data: [
- { type: 'posts', id: '1' },
- { type: 'posts', id: '2' }
- ]
- }
- }
- }
- ]
- assert_equal(expected, hash[:included])
- end
-
- def test_no_duplicates_global
- hash = ActiveModelSerializers::SerializableResource.new(
- @nestedpost1,
- adapter: :json_api,
- include: '*'
- ).serializable_hash
- expected = [
- type: 'nested-posts', id: '2',
- relationships: {
- :"nested-posts" => {
- data: [
- { type: 'nested-posts', id: '1' },
- { type: 'nested-posts', id: '2' }
- ]
- }
- }
- ]
- assert_equal(expected, hash[:included])
- end
-
- def test_no_duplicates_collection_global
- hash = ActiveModelSerializers::SerializableResource.new(
- [@nestedpost1, @nestedpost2],
- adapter: :json_api,
- include: '*'
- ).serializable_hash
- assert_nil(hash[:included])
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/links_test.rb b/test/adapter/json_api/links_test.rb
deleted file mode 100644
index ffbfa303..00000000
--- a/test/adapter/json_api/links_test.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class LinksTest < ActiveSupport::TestCase
- class LinkAuthor < ::Model; associations :posts end
- class LinkAuthorSerializer < ActiveModel::Serializer
- link :self do
- href "http://example.com/link_author/#{object.id}"
- meta stuff: 'value'
- end
- link(:author) { link_author_url(object.id) }
- link(:link_authors) { url_for(controller: 'link_authors', action: 'index', only_path: false) }
- link(:posts) { link_author_posts_url(object.id) }
- link :resource, 'http://example.com/resource'
- link :yet_another do
- "http://example.com/resource/#{object.id}"
- end
- link(:nil) { nil }
- end
-
- def setup
- Rails.application.routes.draw do
- resources :link_authors do
- resources :posts
- end
- end
- @post = Post.new(id: 1337, comments: [], author: nil)
- @author = LinkAuthor.new(id: 1337, posts: [@post])
- end
-
- def test_toplevel_links
- hash = ActiveModelSerializers::SerializableResource.new(
- @post,
- adapter: :json_api,
- links: {
- self: {
- href: 'http://example.com/posts',
- meta: {
- stuff: 'value'
- }
- }
- }
- ).serializable_hash
- expected = {
- self: {
- href: 'http://example.com/posts',
- meta: {
- stuff: 'value'
- }
- }
- }
- assert_equal(expected, hash[:links])
- end
-
- def test_nil_toplevel_links
- hash = ActiveModelSerializers::SerializableResource.new(
- @post,
- adapter: :json_api,
- links: nil
- ).serializable_hash
- refute hash.key?(:links), 'No links key to be output'
- end
-
- def test_nil_toplevel_links_json_adapter
- hash = ActiveModelSerializers::SerializableResource.new(
- @post,
- adapter: :json,
- links: nil
- ).serializable_hash
- refute hash.key?(:links), 'No links key to be output'
- end
-
- def test_resource_links
- hash = serializable(@author, adapter: :json_api).serializable_hash
- expected = {
- self: {
- href: 'http://example.com/link_author/1337',
- meta: {
- stuff: 'value'
- }
- },
- author: 'http://example.com/link_authors/1337',
- :"link-authors" => 'http://example.com/link_authors',
- resource: 'http://example.com/resource',
- posts: 'http://example.com/link_authors/1337/posts',
- :"yet-another" => 'http://example.com/resource/1337'
- }
- assert_equal(expected, hash[:data][:links])
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/pagination_links_test.rb b/test/adapter/json_api/pagination_links_test.rb
deleted file mode 100644
index 736ea2fe..00000000
--- a/test/adapter/json_api/pagination_links_test.rb
+++ /dev/null
@@ -1,193 +0,0 @@
-require 'test_helper'
-require 'will_paginate/array'
-require 'kaminari'
-require 'kaminari/hooks'
-::Kaminari::Hooks.init
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class PaginationLinksTest < ActiveSupport::TestCase
- URI = 'http://example.com'.freeze
-
- def setup
- ActionController::Base.cache_store.clear
- @array = [
- Profile.new(id: 1, name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
- Profile.new(id: 2, name: 'Name 2', description: 'Description 2', comments: 'Comments 2'),
- Profile.new(id: 3, name: 'Name 3', description: 'Description 3', comments: 'Comments 3'),
- Profile.new(id: 4, name: 'Name 4', description: 'Description 4', comments: 'Comments 4'),
- Profile.new(id: 5, name: 'Name 5', description: 'Description 5', comments: 'Comments 5')
- ]
- end
-
- def mock_request(query_parameters = {}, original_url = URI)
- context = Minitest::Mock.new
- context.expect(:request_url, original_url)
- context.expect(:query_parameters, query_parameters)
- context.expect(:key_transform, nil)
- end
-
- def load_adapter(paginated_collection, mock_request = nil)
- render_options = { adapter: :json_api }
- render_options[:serialization_context] = mock_request if mock_request
- serializable(paginated_collection, render_options)
- end
-
- def using_kaminari(page = 2)
- Kaminari.paginate_array(@array).page(page).per(2)
- end
-
- def using_will_paginate(page = 2)
- @array.paginate(page: page, per_page: 2)
- end
-
- def data
- {
- data: [
- { id: '1', type: 'profiles', attributes: { name: 'Name 1', description: 'Description 1' } },
- { id: '2', type: 'profiles', attributes: { name: 'Name 2', description: 'Description 2' } },
- { id: '3', type: 'profiles', attributes: { name: 'Name 3', description: 'Description 3' } },
- { id: '4', type: 'profiles', attributes: { name: 'Name 4', description: 'Description 4' } },
- { id: '5', type: 'profiles', attributes: { name: 'Name 5', description: 'Description 5' } }
- ]
- }
- end
-
- def links
- {
- links: {
- self: "#{URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2",
- first: "#{URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2",
- prev: "#{URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2",
- next: "#{URI}?page%5Bnumber%5D=3&page%5Bsize%5D=2",
- last: "#{URI}?page%5Bnumber%5D=3&page%5Bsize%5D=2"
- }
- }
- end
-
- def last_page_links
- {
- links: {
- self: "#{URI}?page%5Bnumber%5D=3&page%5Bsize%5D=2",
- first: "#{URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2",
- prev: "#{URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2"
- }
- }
- end
-
- def expected_response_when_unpaginatable
- data
- end
-
- def expected_response_with_pagination_links
- {}.tap do |hash|
- hash[:data] = data.values.flatten[2..3]
- hash.merge! links
- end
- end
-
- def expected_response_without_pagination_links
- {}.tap do |hash|
- hash[:data] = data.values.flatten[2..3]
- end
- end
-
- def expected_response_with_pagination_links_and_additional_params
- new_links = links[:links].each_with_object({}) { |(key, value), hash| hash[key] = "#{value}&test=test" }
- {}.tap do |hash|
- hash[:data] = data.values.flatten[2..3]
- hash.merge! links: new_links
- end
- end
-
- def expected_response_with_last_page_pagination_links
- {}.tap do |hash|
- hash[:data] = [data.values.flatten.last]
- hash.merge! last_page_links
- end
- end
-
- def expected_response_with_no_data_pagination_links
- {}.tap do |hash|
- hash[:data] = []
- hash[:links] = {}
- end
- end
-
- def test_pagination_links_using_kaminari
- adapter = load_adapter(using_kaminari, mock_request)
-
- assert_equal expected_response_with_pagination_links, adapter.serializable_hash
- end
-
- def test_pagination_links_using_will_paginate
- adapter = load_adapter(using_will_paginate, mock_request)
-
- assert_equal expected_response_with_pagination_links, adapter.serializable_hash
- end
-
- def test_pagination_links_with_additional_params
- adapter = load_adapter(using_will_paginate, mock_request(test: 'test'))
-
- assert_equal expected_response_with_pagination_links_and_additional_params,
- adapter.serializable_hash
- end
-
- def test_pagination_links_when_zero_results_kaminari
- @array = []
-
- adapter = load_adapter(using_kaminari(1), mock_request)
-
- assert_equal expected_response_with_no_data_pagination_links, adapter.serializable_hash
- end
-
- def test_pagination_links_when_zero_results_will_paginate
- @array = []
-
- adapter = load_adapter(using_will_paginate(1), mock_request)
-
- assert_equal expected_response_with_no_data_pagination_links, adapter.serializable_hash
- end
-
- def test_last_page_pagination_links_using_kaminari
- adapter = load_adapter(using_kaminari(3), mock_request)
-
- assert_equal expected_response_with_last_page_pagination_links, adapter.serializable_hash
- end
-
- def test_last_page_pagination_links_using_will_paginate
- adapter = load_adapter(using_will_paginate(3), mock_request)
-
- assert_equal expected_response_with_last_page_pagination_links, adapter.serializable_hash
- end
-
- def test_not_showing_pagination_links
- adapter = load_adapter(@array, mock_request)
-
- assert_equal expected_response_when_unpaginatable, adapter.serializable_hash
- end
-
- def test_raises_descriptive_error_when_serialization_context_unset
- render_options = { adapter: :json_api }
- adapter = serializable(using_kaminari, render_options)
- exception = assert_raises do
- adapter.as_json
- end
- exception_class = ActiveModelSerializers::Adapter::JsonApi::PaginationLinks::MissingSerializationContextError
- assert_equal exception_class, exception.class
- assert_match(/CollectionSerializer#paginated\?/, exception.message)
- end
-
- def test_pagination_links_not_present_when_disabled
- ActiveModel::Serializer.config.jsonapi_pagination_links_enabled = false
- adapter = load_adapter(using_kaminari, mock_request)
-
- assert_equal expected_response_without_pagination_links, adapter.serializable_hash
- ensure
- ActiveModel::Serializer.config.jsonapi_pagination_links_enabled = true
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/parse_test.rb b/test/adapter/json_api/parse_test.rb
deleted file mode 100644
index bee79c8c..00000000
--- a/test/adapter/json_api/parse_test.rb
+++ /dev/null
@@ -1,137 +0,0 @@
-require 'test_helper'
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- module Deserialization
- class ParseTest < Minitest::Test
- def setup
- @hash = {
- 'data' => {
- 'type' => 'photos',
- 'id' => 'zorglub',
- 'attributes' => {
- 'title' => 'Ember Hamster',
- 'src' => 'http://example.com/images/productivity.png'
- },
- 'relationships' => {
- 'author' => {
- 'data' => nil
- },
- 'photographer' => {
- 'data' => { 'type' => 'people', 'id' => '9' }
- },
- 'comments' => {
- 'data' => [
- { 'type' => 'comments', 'id' => '1' },
- { 'type' => 'comments', 'id' => '2' }
- ]
- }
- }
- }
- }
- @params = ActionController::Parameters.new(@hash)
- @expected = {
- id: 'zorglub',
- title: 'Ember Hamster',
- src: 'http://example.com/images/productivity.png',
- author_id: nil,
- photographer_id: '9',
- comment_ids: %w(1 2)
- }
-
- @illformed_payloads = [nil,
- {},
- {
- 'data' => nil
- }, {
- 'data' => { 'attributes' => [] }
- }, {
- 'data' => { 'relationships' => [] }
- }, {
- 'data' => {
- 'relationships' => { 'rel' => nil }
- }
- }, {
- 'data' => {
- 'relationships' => { 'rel' => {} }
- }
- }]
- end
-
- def test_hash
- parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(@hash)
- assert_equal(@expected, parsed_hash)
- end
-
- def test_actioncontroller_parameters
- assert_equal(false, @params.permitted?)
- parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(@params)
- assert_equal(@expected, parsed_hash)
- end
-
- def test_illformed_payloads_safe
- @illformed_payloads.each do |p|
- parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse(p)
- assert_equal({}, parsed_hash)
- end
- end
-
- def test_illformed_payloads_unsafe
- @illformed_payloads.each do |p|
- assert_raises(InvalidDocument) do
- ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(p)
- end
- end
- end
-
- def test_filter_fields_only
- parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(@hash, only: [:id, :title, :author])
- expected = {
- id: 'zorglub',
- title: 'Ember Hamster',
- author_id: nil
- }
- assert_equal(expected, parsed_hash)
- end
-
- def test_filter_fields_except
- parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(@hash, except: [:id, :title, :author])
- expected = {
- src: 'http://example.com/images/productivity.png',
- photographer_id: '9',
- comment_ids: %w(1 2)
- }
- assert_equal(expected, parsed_hash)
- end
-
- def test_keys
- parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(@hash, keys: { author: :user, title: :post_title })
- expected = {
- id: 'zorglub',
- post_title: 'Ember Hamster',
- src: 'http://example.com/images/productivity.png',
- user_id: nil,
- photographer_id: '9',
- comment_ids: %w(1 2)
- }
- assert_equal(expected, parsed_hash)
- end
-
- def test_polymorphic
- parsed_hash = ActiveModelSerializers::Adapter::JsonApi::Deserialization.parse!(@hash, polymorphic: [:photographer])
- expected = {
- id: 'zorglub',
- title: 'Ember Hamster',
- src: 'http://example.com/images/productivity.png',
- author_id: nil,
- photographer_id: '9',
- photographer_type: 'people',
- comment_ids: %w(1 2)
- }
- assert_equal(expected, parsed_hash)
- end
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/relationship_test.rb b/test/adapter/json_api/relationship_test.rb
deleted file mode 100644
index cfd5be85..00000000
--- a/test/adapter/json_api/relationship_test.rb
+++ /dev/null
@@ -1,397 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class RelationshipTest < ActiveSupport::TestCase
- def test_relationship_with_data
- expected = {
- data: {
- id: '1',
- type: 'blogs'
- }
- }
-
- model_attributes = { blog: Blog.new(id: 1) }
- relationship_name = :blog
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_one :blog
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_with_nil_model
- expected = { data: nil }
-
- model_attributes = { blog: nil }
- relationship_name = :blog
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_one :blog
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_with_data_array
- expected = {
- data: [
- {
- id: '1',
- type: 'posts'
- },
- {
- id: '2',
- type: 'posts'
- }
- ]
- }
-
- model_attributes = { posts: [Post.new(id: 1), Post.new(id: 2)] }
- relationship_name = :posts
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_many :posts
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_data_not_included
- expected = { meta: {} }
-
- model_attributes = { blog: :does_not_matter }
- relationship_name = :blog
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_one :blog do
- include_data false
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_many_links
- expected = {
- links: {
- self: 'a link',
- related: 'another link'
- }
- }
-
- model_attributes = { blog: :does_not_matter }
- relationship_name = :blog
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_one :blog do
- include_data false
- link :self, 'a link'
- link :related, 'another link'
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_block_link_with_meta
- expected = {
- links: {
- self: {
- href: '1',
- meta: { id: 1 }
- }
- }
- }
-
- model_attributes = { blog: Blog.new(id: 1) }
- relationship_name = :blog
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_one :blog do
- include_data false
- link :self do
- href object.blog.id.to_s
- meta(id: object.blog.id)
- end
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_simple_meta
- expected = { meta: { id: '1' } }
-
- model_attributes = { blog: Blog.new(id: 1) }
- relationship_name = :blog
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_one :blog do
- include_data false
- meta(id: object.blog.id.to_s)
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_block_meta
- expected = {
- meta: {
- id: 1
- }
- }
-
- model_attributes = { blog: Blog.new(id: 1) }
- relationship_name = :blog
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_one :blog do
- include_data false
- meta(id: object.blog.id)
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_simple_link
- expected = {
- data: {
- id: '1337',
- type: 'bios'
- },
- links: {
- self: '//example.com/link_author/relationships/bio'
- }
- }
-
- model_attributes = { bio: Bio.new(id: 1337) }
- relationship_name = :bio
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_one :bio do
- link :self, '//example.com/link_author/relationships/bio'
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_block_link
- expected = {
- data: { id: '1337', type: 'profiles' },
- links: { related: '//example.com/profiles/1337' }
- }
-
- model_attributes = { profile: Profile.new(id: 1337) }
- relationship_name = :profile
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_one :profile do
- id = object.profile.id
- link :related do
- "//example.com/profiles/#{id}" if id != 123
- end
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_with_everything
- expected = {
- data: [{ id: '1337', type: 'likes' }],
- links: {
- related: {
- href: '//example.com/likes/1337',
- meta: { ids: '1337' }
- }
- },
- meta: { liked: true }
- }
-
- model_attributes = { likes: [Like.new(id: 1337)] }
- relationship_name = :likes
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_many :likes do
- link :related do
- ids = object.likes.map(&:id).join(',')
- href "//example.com/likes/#{ids}"
- meta ids: ids
- end
- meta liked: object.likes.any?
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_nil_link
- expected = {
- data: { id: '123', type: 'profiles' }
- }
-
- model_attributes = { profile: Profile.new(id: 123) }
- relationship_name = :profile
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_one :profile do
- id = object.profile.id
- link :related do
- "//example.com/profiles/#{id}" if id != 123
- end
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_block_link_href
- expected = {
- data: [{ id: '1337', type: 'locations' }],
- links: {
- related: { href: '//example.com/locations/1337' }
- }
- }
-
- model_attributes = { locations: [Location.new(id: 1337)] }
- relationship_name = :locations
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_many :locations do
- link :related do
- ids = object.locations.map(&:id).join(',')
- href "//example.com/locations/#{ids}"
- end
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_block_link_href_and_meta
- expected = {
- data: [{ id: '1337', type: 'posts' }],
- links: {
- related: {
- href: '//example.com/posts/1337',
- meta: { ids: '1337' }
- }
- }
- }
-
- model_attributes = { posts: [Post.new(id: 1337, comments: [], author: nil)] }
- relationship_name = :posts
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_many :posts do
- link :related do
- ids = object.posts.map(&:id).join(',')
- href "//example.com/posts/#{ids}"
- meta ids: ids
- end
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_block_link_meta
- expected = {
- data: [{ id: '1337', type: 'comments' }],
- links: {
- self: {
- meta: { ids: [1] }
- }
- }
- }
-
- model_attributes = { comments: [Comment.new(id: 1337)] }
- relationship_name = :comments
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_many :comments do
- link :self do
- meta ids: [1]
- end
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_meta
- expected = {
- data: [{ id: 'from-serializer-method', type: 'roles' }],
- meta: { count: 1 }
- }
-
- model_attributes = { roles: [Role.new(id: 'from-record')] }
- relationship_name = :roles
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_many :roles do |serializer|
- meta count: object.roles.count
- serializer.cached_roles
- end
- def cached_roles
- [
- Role.new(id: 'from-serializer-method')
- ]
- end
- end
- assert_equal(expected, actual)
- end
-
- def test_relationship_not_including_data
- expected = {
- links: { self: '//example.com/link_author/relationships/blog' }
- }
-
- model_attributes = { blog: Object }
- relationship_name = :blog
- model = new_model(model_attributes)
- model.define_singleton_method(:read_attribute_for_serialization) do |attr|
- fail 'should not be called' if attr == :blog
- super(attr)
- end
- assert_nothing_raised do
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- has_one :blog do
- link :self, '//example.com/link_author/relationships/blog'
- include_data false
- end
- end
- assert_equal(expected, actual)
- end
- end
-
- def test_relationship_including_data_explicit
- expected = {
- data: { id: '1337', type: 'authors' },
- meta: { name: 'Dan Brown' }
- }
-
- model_attributes = { reviewer: Author.new(id: 1337) }
- relationship_name = :reviewer
- model = new_model(model_attributes)
- actual = build_serializer_and_serialize_relationship(model, relationship_name) do
- belongs_to :reviewer do
- meta name: 'Dan Brown'
- include_data true
- end
- end
- assert_equal(expected, actual)
- end
-
- private
-
- def build_serializer_and_serialize_relationship(model, relationship_name, &block)
- serializer_class = Class.new(ActiveModel::Serializer, &block)
- hash = serializable(model, serializer: serializer_class, adapter: :json_api).serializable_hash
- hash[:data][:relationships][relationship_name]
- end
-
- def new_model(model_attributes)
- Class.new(ActiveModelSerializers::Model) do
- attributes(*model_attributes.keys)
-
- def self.name
- 'TestModel'
- end
- end.new(model_attributes)
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/resource_identifier_test.rb b/test/adapter/json_api/resource_identifier_test.rb
deleted file mode 100644
index 62b7d93b..00000000
--- a/test/adapter/json_api/resource_identifier_test.rb
+++ /dev/null
@@ -1,110 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class ResourceIdentifierTest < ActiveSupport::TestCase
- class WithDefinedTypeSerializer < ActiveModel::Serializer
- type 'with_defined_type'
- end
-
- class WithDefinedIdSerializer < ActiveModel::Serializer
- def id
- 'special_id'
- end
- end
-
- class FragmentedSerializer < ActiveModel::Serializer
- cache only: :id
-
- def id
- 'special_id'
- end
- end
-
- setup do
- @model = Author.new(id: 1, name: 'Steve K.')
- ActionController::Base.cache_store.clear
- end
-
- def test_defined_type
- test_type(WithDefinedTypeSerializer, 'with-defined-type')
- end
-
- def test_singular_type
- test_type_inflection(AuthorSerializer, 'author', :singular)
- end
-
- def test_plural_type
- test_type_inflection(AuthorSerializer, 'authors', :plural)
- end
-
- def test_type_with_namespace
- Object.const_set(:Admin, Module.new)
- model = Class.new(::Model)
- Admin.const_set(:PowerUser, model)
- serializer = Class.new(ActiveModel::Serializer)
- Admin.const_set(:PowerUserSerializer, serializer)
- with_namespace_separator '--' do
- admin_user = Admin::PowerUser.new
- serializer = Admin::PowerUserSerializer.new(admin_user)
- expected = {
- id: admin_user.id,
- type: 'admin--power-users'
- }
-
- identifier = ResourceIdentifier.new(serializer, {})
- actual = identifier.as_json
- assert_equal(expected, actual)
- end
- end
-
- def test_id_defined_on_object
- test_id(AuthorSerializer, @model.id.to_s)
- end
-
- def test_id_defined_on_serializer
- test_id(WithDefinedIdSerializer, 'special_id')
- end
-
- def test_id_defined_on_fragmented
- test_id(FragmentedSerializer, 'special_id')
- end
-
- private
-
- def test_type_inflection(serializer_class, expected_type, inflection)
- original_inflection = ActiveModelSerializers.config.jsonapi_resource_type
- ActiveModelSerializers.config.jsonapi_resource_type = inflection
- test_type(serializer_class, expected_type)
- ensure
- ActiveModelSerializers.config.jsonapi_resource_type = original_inflection
- end
-
- def test_type(serializer_class, expected_type)
- serializer = serializer_class.new(@model)
- resource_identifier = ResourceIdentifier.new(serializer, nil)
- expected = {
- id: @model.id.to_s,
- type: expected_type
- }
-
- assert_equal(expected, resource_identifier.as_json)
- end
-
- def test_id(serializer_class, id)
- serializer = serializer_class.new(@model)
- resource_identifier = ResourceIdentifier.new(serializer, nil)
- inflection = ActiveModelSerializers.config.jsonapi_resource_type
- type = @model.class.model_name.send(inflection)
- expected = {
- id: id,
- type: type
- }
-
- assert_equal(expected, resource_identifier.as_json)
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/resource_meta_test.rb b/test/adapter/json_api/resource_meta_test.rb
deleted file mode 100644
index fa281f30..00000000
--- a/test/adapter/json_api/resource_meta_test.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- module Adapter
- class JsonApi
- class ResourceMetaTest < Minitest::Test
- class MetaHashPostSerializer < ActiveModel::Serializer
- attributes :id
- meta stuff: 'value'
- end
-
- class MetaBlockPostSerializer < ActiveModel::Serializer
- attributes :id
- meta do
- { comments_count: object.comments.count }
- end
- end
-
- class MetaBlockPostBlankMetaSerializer < ActiveModel::Serializer
- attributes :id
- meta do
- {}
- end
- end
-
- class MetaBlockPostEmptyStringSerializer < ActiveModel::Serializer
- attributes :id
- meta do
- ''
- end
- end
-
- def setup
- @post = Post.new(id: 1337, comments: [], author: nil)
- end
-
- def test_meta_hash_object_resource
- hash = ActiveModelSerializers::SerializableResource.new(
- @post,
- serializer: MetaHashPostSerializer,
- adapter: :json_api
- ).serializable_hash
- expected = {
- stuff: 'value'
- }
- assert_equal(expected, hash[:data][:meta])
- end
-
- def test_meta_block_object_resource
- hash = ActiveModelSerializers::SerializableResource.new(
- @post,
- serializer: MetaBlockPostSerializer,
- adapter: :json_api
- ).serializable_hash
- expected = {
- :"comments-count" => @post.comments.count
- }
- assert_equal(expected, hash[:data][:meta])
- end
-
- def test_meta_object_resource_in_array
- post2 = Post.new(id: 1339, comments: [Comment.new])
- posts = [@post, post2]
- hash = ActiveModelSerializers::SerializableResource.new(
- posts,
- each_serializer: MetaBlockPostSerializer,
- adapter: :json_api
- ).serializable_hash
- expected = {
- data: [
- { id: '1337', type: 'posts', meta: { :"comments-count" => 0 } },
- { id: '1339', type: 'posts', meta: { :"comments-count" => 1 } }
- ]
- }
- assert_equal(expected, hash)
- end
-
- def test_meta_object_blank_omitted
- hash = ActiveModelSerializers::SerializableResource.new(
- @post,
- serializer: MetaBlockPostBlankMetaSerializer,
- adapter: :json_api
- ).serializable_hash
- refute hash[:data].key? :meta
- end
-
- def test_meta_object_empty_string_omitted
- hash = ActiveModelSerializers::SerializableResource.new(
- @post,
- serializer: MetaBlockPostEmptyStringSerializer,
- adapter: :json_api
- ).serializable_hash
- refute hash[:data].key? :meta
- end
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/toplevel_jsonapi_test.rb b/test/adapter/json_api/toplevel_jsonapi_test.rb
deleted file mode 100644
index 7b0357e5..00000000
--- a/test/adapter/json_api/toplevel_jsonapi_test.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class TopLevelJsonApiTest < ActiveSupport::TestCase
- def setup
- @author = Author.new(id: 1, name: 'Steve K.')
- @author.bio = nil
- @author.roles = []
- @blog = Blog.new(id: 23, name: 'AMS Blog')
- @post = Post.new(id: 42, title: 'New Post', body: 'Body')
- @anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
- @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @post.comments = [@comment]
- @post.blog = @blog
- @anonymous_post.comments = []
- @anonymous_post.blog = nil
- @comment.post = @post
- @comment.author = nil
- @post.author = @author
- @anonymous_post.author = nil
- @blog = Blog.new(id: 1, name: 'My Blog!!')
- @blog.writer = @author
- @blog.articles = [@post, @anonymous_post]
- @author.posts = []
- end
-
- def test_toplevel_jsonapi_defaults_to_false
- assert_equal config.fetch(:jsonapi_include_toplevel_object), false
- end
-
- def test_disable_toplevel_jsonapi
- with_config(jsonapi_include_toplevel_object: false) do
- hash = serialize(@post)
- assert_nil(hash[:jsonapi])
- end
- end
-
- def test_enable_toplevel_jsonapi
- with_config(jsonapi_include_toplevel_object: true) do
- hash = serialize(@post)
- refute_nil(hash[:jsonapi])
- end
- end
-
- def test_default_toplevel_jsonapi_version
- with_config(jsonapi_include_toplevel_object: true) do
- hash = serialize(@post)
- assert_equal('1.0', hash[:jsonapi][:version])
- end
- end
-
- def test_toplevel_jsonapi_no_meta
- with_config(jsonapi_include_toplevel_object: true) do
- hash = serialize(@post)
- assert_nil(hash[:jsonapi][:meta])
- end
- end
-
- def test_toplevel_jsonapi_meta
- new_config = {
- jsonapi_include_toplevel_object: true,
- jsonapi_toplevel_meta: {
- 'copyright' => 'Copyright 2015 Example Corp.'
- }
- }
- with_config(new_config) do
- hash = serialize(@post)
- assert_equal(new_config[:jsonapi_toplevel_meta], hash.fetch(:jsonapi).fetch(:meta))
- end
- end
-
- private
-
- def serialize(resource, options = {})
- serializable(resource, { adapter: :json_api }.merge!(options)).serializable_hash
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/transform_test.rb b/test/adapter/json_api/transform_test.rb
deleted file mode 100644
index 887ec835..00000000
--- a/test/adapter/json_api/transform_test.rb
+++ /dev/null
@@ -1,512 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonApi
- class KeyCaseTest < ActiveSupport::TestCase
- class Post < ::Model
- attributes :title, :body, :publish_at
- associations :author, :comments
- end
- class Author < ::Model
- attributes :first_name, :last_name
- end
- class Comment < ::Model
- attributes :body
- associations :author, :post
- end
-
- class PostSerializer < ActiveModel::Serializer
- type 'posts'
- attributes :title, :body, :publish_at
- belongs_to :author
- has_many :comments
-
- link(:self) { post_url(object.id) }
- link(:post_authors) { post_authors_url(object.id) }
- link(:subscriber_comments) { post_comments_url(object.id) }
-
- meta do
- {
- rating: 5,
- favorite_count: 10
- }
- end
- end
-
- class AuthorSerializer < ActiveModel::Serializer
- type 'authors'
- attributes :first_name, :last_name
- end
-
- class CommentSerializer < ActiveModel::Serializer
- type 'comments'
- attributes :body
- belongs_to :author
- end
-
- def mock_request(transform = nil)
- context = Minitest::Mock.new
- context.expect(:request_url, URI)
- context.expect(:query_parameters, {})
- context.expect(:url_helpers, Rails.application.routes.url_helpers)
- @options = {}
- @options[:key_transform] = transform if transform
- @options[:serialization_context] = context
- end
-
- def setup
- Rails.application.routes.draw do
- resources :posts do
- resources :authors
- resources :comments
- end
- end
- @publish_at = 1.day.from_now
- @author = Author.new(id: 1, first_name: 'Bob', last_name: 'Jones')
- @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],
- publish_at: @publish_at)
- @comment1.post = @post
- @comment2.post = @post
- end
-
- def test_success_document_transform_default
- mock_request
- serializer = PostSerializer.new(@post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- result = adapter.serializable_hash
- assert_equal({
- data: {
- id: '1337',
- type: 'posts',
- attributes: {
- title: 'Title 1',
- body: 'Body 1',
- :"publish-at" => @publish_at
- },
- relationships: {
- author: {
- data: { id: '1', type: 'authors' }
- },
- comments: {
- data: [
- { id: '7', type: 'comments' },
- { id: '12', type: 'comments' }
- ]
- }
- },
- links: {
- self: 'http://example.com/posts/1337',
- :"post-authors" => 'http://example.com/posts/1337/authors',
- :"subscriber-comments" => 'http://example.com/posts/1337/comments'
- },
- meta: { rating: 5, :"favorite-count" => 10 }
- }
- }, result)
- end
-
- def test_success_document_transform_global_config
- mock_request
- result = with_config(key_transform: :camel_lower) do
- serializer = PostSerializer.new(@post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- adapter.serializable_hash
- end
- assert_equal({
- data: {
- id: '1337',
- type: 'posts',
- attributes: {
- title: 'Title 1',
- body: 'Body 1',
- publishAt: @publish_at
- },
- relationships: {
- author: {
- data: { id: '1', type: 'authors' }
- },
- comments: {
- data: [
- { id: '7', type: 'comments' },
- { id: '12', type: 'comments' }
- ]
- }
- },
- links: {
- self: 'http://example.com/posts/1337',
- postAuthors: 'http://example.com/posts/1337/authors',
- subscriberComments: 'http://example.com/posts/1337/comments'
- },
- meta: { rating: 5, favoriteCount: 10 }
- }
- }, result)
- end
-
- def test_success_doc_transform_serialization_ctx_overrides_global
- mock_request(:camel)
- result = with_config(key_transform: :camel_lower) do
- serializer = PostSerializer.new(@post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- adapter.serializable_hash
- end
- assert_equal({
- Data: {
- Id: '1337',
- Type: 'Posts',
- Attributes: {
- Title: 'Title 1',
- Body: 'Body 1',
- PublishAt: @publish_at
- },
- Relationships: {
- Author: {
- Data: { Id: '1', Type: 'Authors' }
- },
- Comments: {
- Data: [
- { Id: '7', Type: 'Comments' },
- { Id: '12', Type: 'Comments' }
- ]
- }
- },
- Links: {
- Self: 'http://example.com/posts/1337',
- PostAuthors: 'http://example.com/posts/1337/authors',
- SubscriberComments: 'http://example.com/posts/1337/comments'
- },
- Meta: { Rating: 5, FavoriteCount: 10 }
- }
- }, result)
- end
-
- def test_success_document_transform_dash
- mock_request(:dash)
- serializer = PostSerializer.new(@post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- result = adapter.serializable_hash
- assert_equal({
- data: {
- id: '1337',
- type: 'posts',
- attributes: {
- title: 'Title 1',
- body: 'Body 1',
- :"publish-at" => @publish_at
- },
- relationships: {
- author: {
- data: { id: '1', type: 'authors' }
- },
- comments: {
- data: [
- { id: '7', type: 'comments' },
- { id: '12', type: 'comments' }
- ]
- }
- },
- links: {
- self: 'http://example.com/posts/1337',
- :"post-authors" => 'http://example.com/posts/1337/authors',
- :"subscriber-comments" => 'http://example.com/posts/1337/comments'
- },
- meta: { rating: 5, :"favorite-count" => 10 }
- }
- }, result)
- end
-
- def test_success_document_transform_unaltered
- mock_request(:unaltered)
- serializer = PostSerializer.new(@post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- result = adapter.serializable_hash
- assert_equal({
- data: {
- id: '1337',
- type: 'posts',
- attributes: {
- title: 'Title 1',
- body: 'Body 1',
- publish_at: @publish_at
- },
- relationships: {
- author: {
- data: { id: '1', type: 'authors' }
- },
- comments: {
- data: [
- { id: '7', type: 'comments' },
- { id: '12', type: 'comments' }
- ]
- }
- },
- links: {
- self: 'http://example.com/posts/1337',
- post_authors: 'http://example.com/posts/1337/authors',
- subscriber_comments: 'http://example.com/posts/1337/comments'
- },
- meta: { rating: 5, favorite_count: 10 }
- }
- }, result)
- end
-
- def test_success_document_transform_undefined
- mock_request(:zoot)
- serializer = PostSerializer.new(@post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- exception = assert_raises NoMethodError do
- adapter.serializable_hash
- end
- assert_match(/undefined method.*zoot/, exception.message)
- end
-
- def test_success_document_transform_camel
- mock_request(:camel)
- serializer = PostSerializer.new(@post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- result = adapter.serializable_hash
- assert_equal({
- Data: {
- Id: '1337',
- Type: 'Posts',
- Attributes: {
- Title: 'Title 1',
- Body: 'Body 1',
- PublishAt: @publish_at
- },
- Relationships: {
- Author: {
- Data: { Id: '1', Type: 'Authors' }
- },
- Comments: {
- Data: [
- { Id: '7', Type: 'Comments' },
- { Id: '12', Type: 'Comments' }
- ]
- }
- },
- Links: {
- Self: 'http://example.com/posts/1337',
- PostAuthors: 'http://example.com/posts/1337/authors',
- SubscriberComments: 'http://example.com/posts/1337/comments'
- },
- Meta: { Rating: 5, FavoriteCount: 10 }
- }
- }, result)
- end
-
- def test_success_document_transform_camel_lower
- mock_request(:camel_lower)
- serializer = PostSerializer.new(@post)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- result = adapter.serializable_hash
- assert_equal({
- data: {
- id: '1337',
- type: 'posts',
- attributes: {
- title: 'Title 1',
- body: 'Body 1',
- publishAt: @publish_at
- },
- relationships: {
- author: {
- data: { id: '1', type: 'authors' }
- },
- comments: {
- data: [
- { id: '7', type: 'comments' },
- { id: '12', type: 'comments' }
- ]
- }
- },
- links: {
- self: 'http://example.com/posts/1337',
- postAuthors: 'http://example.com/posts/1337/authors',
- subscriberComments: 'http://example.com/posts/1337/comments'
- },
- meta: { rating: 5, favoriteCount: 10 }
- }
- }, result)
- end
-
- def test_error_document_transform_default
- mock_request
- resource = ModelWithErrors.new
- resource.errors.add(:published_at, 'must be in the future')
- resource.errors.add(:title, 'must be longer')
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- result = adapter.serializable_hash
- expected_errors_object = {
- errors: [
- {
- source: { pointer: '/data/attributes/published-at' },
- detail: 'must be in the future'
- },
- {
- source: { pointer: '/data/attributes/title' },
- detail: 'must be longer'
- }
- ]
- }
- assert_equal expected_errors_object, result
- end
-
- def test_error_document_transform_global_config
- mock_request
- result = with_config(key_transform: :camel) do
- resource = ModelWithErrors.new
- resource.errors.add(:published_at, 'must be in the future')
- resource.errors.add(:title, 'must be longer')
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- adapter.serializable_hash
- end
- expected_errors_object = {
- Errors: [
- {
- Source: { Pointer: '/data/attributes/PublishedAt' },
- Detail: 'must be in the future'
- },
- {
- Source: { Pointer: '/data/attributes/Title' },
- Detail: 'must be longer'
- }
- ]
- }
- assert_equal expected_errors_object, result
- end
-
- def test_error_document_transform_serialization_ctx_overrides_global
- mock_request(:camel)
- result = with_config(key_transform: :camel_lower) do
- resource = ModelWithErrors.new
- resource.errors.add(:published_at, 'must be in the future')
- resource.errors.add(:title, 'must be longer')
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- adapter.serializable_hash
- end
- expected_errors_object = {
- Errors: [
- {
- Source: { Pointer: '/data/attributes/PublishedAt' },
- Detail: 'must be in the future'
- },
- {
- Source: { Pointer: '/data/attributes/Title' },
- Detail: 'must be longer'
- }
- ]
- }
- assert_equal expected_errors_object, result
- end
-
- def test_error_document_transform_dash
- mock_request(:dash)
-
- resource = ModelWithErrors.new
- resource.errors.add(:published_at, 'must be in the future')
- resource.errors.add(:title, 'must be longer')
-
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- result = adapter.serializable_hash
-
- expected_errors_object = {
- errors: [
- {
- source: { pointer: '/data/attributes/published-at' },
- detail: 'must be in the future'
- },
- {
- source: { pointer: '/data/attributes/title' },
- detail: 'must be longer'
- }
- ]
- }
- assert_equal expected_errors_object, result
- end
-
- def test_error_document_transform_unaltered
- mock_request(:unaltered)
-
- resource = ModelWithErrors.new
- resource.errors.add(:published_at, 'must be in the future')
- resource.errors.add(:title, 'must be longer')
-
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- result = adapter.serializable_hash
-
- expected_errors_object = {
- errors: [
- { source: { pointer: '/data/attributes/published_at' }, detail: 'must be in the future' },
- { source: { pointer: '/data/attributes/title' }, detail: 'must be longer' }
- ]
- }
- assert_equal expected_errors_object, result
- end
-
- def test_error_document_transform_undefined
- mock_request(:krazy)
-
- resource = ModelWithErrors.new
- resource.errors.add(:published_at, 'must be in the future')
- resource.errors.add(:title, 'must be longer')
-
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
-
- exception = assert_raises NoMethodError do
- adapter.serializable_hash
- end
- assert_match(/undefined method.*krazy/, exception.message)
- end
-
- def test_error_document_transform_camel
- mock_request(:camel)
-
- resource = ModelWithErrors.new
- resource.errors.add(:published_at, 'must be in the future')
- resource.errors.add(:title, 'must be longer')
-
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- result = adapter.serializable_hash
-
- expected_errors_object = {
- Errors: [
- { Source: { Pointer: '/data/attributes/PublishedAt' }, Detail: 'must be in the future' },
- { Source: { Pointer: '/data/attributes/Title' }, Detail: 'must be longer' }
- ]
- }
- assert_equal expected_errors_object, result
- end
-
- def test_error_document_transform_camel_lower
- mock_request(:camel_lower)
-
- resource = ModelWithErrors.new
- resource.errors.add(:published_at, 'must be in the future')
- resource.errors.add(:title, 'must be longer')
-
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
- result = adapter.serializable_hash
-
- expected_errors_object = {
- errors: [
- { source: { pointer: '/data/attributes/publishedAt' }, detail: 'must be in the future' },
- { source: { pointer: '/data/attributes/title' }, detail: 'must be longer' }
- ]
- }
- assert_equal expected_errors_object, result
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_api/type_test.rb b/test/adapter/json_api/type_test.rb
deleted file mode 100644
index 40b84cf2..00000000
--- a/test/adapter/json_api/type_test.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- module Adapter
- class JsonApi
- class TypeTest < ActiveSupport::TestCase
- class StringTypeSerializer < ActiveModel::Serializer
- attribute :name
- type 'profile'
- end
-
- class SymbolTypeSerializer < ActiveModel::Serializer
- attribute :name
- type :profile
- end
-
- setup do
- @author = Author.new(id: 1, name: 'Steve K.')
- end
-
- def test_config_plural
- with_jsonapi_resource_type :plural do
- assert_type(@author, 'authors')
- end
- end
-
- def test_config_singular
- with_jsonapi_resource_type :singular do
- assert_type(@author, 'author')
- end
- end
-
- def test_explicit_string_type_value
- assert_type(@author, 'profile', serializer: StringTypeSerializer)
- end
-
- def test_explicit_symbol_type_value
- assert_type(@author, 'profile', serializer: SymbolTypeSerializer)
- end
-
- private
-
- def assert_type(resource, expected_type, opts = {})
- opts = opts.reverse_merge(adapter: :json_api)
- hash = serializable(resource, opts).serializable_hash
- assert_equal(expected_type, hash.fetch(:data).fetch(:type))
- end
-
- def with_jsonapi_resource_type(inflection)
- old_inflection = ActiveModelSerializers.config.jsonapi_resource_type
- ActiveModelSerializers.config.jsonapi_resource_type = inflection
- yield
- ensure
- ActiveModelSerializers.config.jsonapi_resource_type = old_inflection
- end
- end
- end
- end
- end
-end
diff --git a/test/adapter/json_test.rb b/test/adapter/json_test.rb
deleted file mode 100644
index f7f178f8..00000000
--- a/test/adapter/json_test.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class JsonTest < ActiveSupport::TestCase
- def setup
- ActionController::Base.cache_store.clear
- @author = Author.new(id: 1, name: 'Steve K.')
- @post = Post.new(id: 1, title: 'New Post', body: 'Body')
- @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
- @post.comments = [@first_comment, @second_comment]
- @first_comment.post = @post
- @second_comment.post = @post
- @post.author = @author
- @blog = Blog.new(id: 1, name: 'My Blog!!')
- @post.blog = @blog
-
- @serializer = PostSerializer.new(@post)
- @adapter = ActiveModelSerializers::Adapter::Json.new(@serializer)
- end
-
- def test_has_many
- assert_equal([
- { id: 1, body: 'ZOMG A COMMENT' },
- { id: 2, body: 'ZOMG ANOTHER COMMENT' }
- ], @adapter.serializable_hash[:post][:comments])
- end
-
- def test_custom_keys
- serializer = PostWithCustomKeysSerializer.new(@post)
- adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
-
- assert_equal({
- id: 1,
- reviews: [
- { id: 1, body: 'ZOMG A COMMENT' },
- { id: 2, body: 'ZOMG ANOTHER COMMENT' }
- ],
- writer: { id: 1, name: 'Steve K.' },
- site: { id: 1, name: 'My Blog!!' }
- }, adapter.serializable_hash[:post])
- end
- end
- end
-end
diff --git a/test/adapter/null_test.rb b/test/adapter/null_test.rb
deleted file mode 100644
index 4e701db1..00000000
--- a/test/adapter/null_test.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- module Adapter
- class NullTest < ActiveSupport::TestCase
- def setup
- profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- serializer = ProfileSerializer.new(profile)
-
- @adapter = Null.new(serializer)
- end
-
- def test_serializable_hash
- assert_equal({}, @adapter.serializable_hash)
- end
-
- def test_it_returns_empty_json
- assert_equal('{}', @adapter.to_json)
- end
- end
- end
-end
diff --git a/test/adapter/polymorphic_test.rb b/test/adapter/polymorphic_test.rb
deleted file mode 100644
index 87d5ff51..00000000
--- a/test/adapter/polymorphic_test.rb
+++ /dev/null
@@ -1,171 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- module Adapter
- class PolymorphicTest < ActiveSupport::TestCase
- setup do
- @employee = Employee.new(id: 42, name: 'Zoop Zoopler', email: 'zoop@example.com')
- @picture = @employee.pictures.new(id: 1, title: 'headshot-1.jpg')
- @picture.imageable = @employee
- end
-
- def serialization(resource, adapter = :attributes)
- serializable(resource, adapter: adapter, serializer: PolymorphicBelongsToSerializer).as_json
- end
-
- def tag_serialization(adapter = :attributes)
- tag = PolyTag.new(id: 1, phrase: 'foo')
- tag.object_tags << ObjectTag.new(id: 1, poly_tag_id: 1, taggable: @employee)
- tag.object_tags << ObjectTag.new(id: 5, poly_tag_id: 1, taggable: @picture)
- serializable(tag, adapter: adapter, serializer: PolymorphicTagSerializer, include: '*.*').as_json
- end
-
- def test_attributes_serialization
- expected =
- {
- id: 1,
- title: 'headshot-1.jpg',
- imageable: {
- type: 'employee',
- employee: {
- id: 42,
- name: 'Zoop Zoopler'
- }
- }
- }
-
- assert_equal(expected, serialization(@picture))
- end
-
- def test_attributes_serialization_without_polymorphic_association
- expected =
- {
- id: 2,
- title: 'headshot-2.jpg',
- imageable: nil
- }
-
- simple_picture = Picture.new(id: 2, title: 'headshot-2.jpg')
- assert_equal(expected, serialization(simple_picture))
- end
-
- def test_attributes_serialization_with_polymorphic_has_many
- expected =
- {
- id: 1,
- phrase: 'foo',
- object_tags: [
- {
- id: 1,
- taggable: {
- type: 'employee',
- employee: {
- id: 42
- }
- }
- },
- {
- id: 5,
- taggable: {
- type: 'picture',
- picture: {
- id: 1
- }
- }
- }
- ]
- }
- assert_equal(expected, tag_serialization)
- end
-
- def test_json_serialization
- expected =
- {
- picture: {
- id: 1,
- title: 'headshot-1.jpg',
- imageable: {
- type: 'employee',
- employee: {
- id: 42,
- name: 'Zoop Zoopler'
- }
- }
- }
- }
-
- assert_equal(expected, serialization(@picture, :json))
- end
-
- def test_json_serialization_without_polymorphic_association
- expected =
- {
- picture: {
- id: 2,
- title: 'headshot-2.jpg',
- imageable: nil
- }
- }
-
- simple_picture = Picture.new(id: 2, title: 'headshot-2.jpg')
- assert_equal(expected, serialization(simple_picture, :json))
- end
-
- def test_json_serialization_with_polymorphic_has_many
- expected =
- {
- poly_tag: {
- id: 1,
- phrase: 'foo',
- object_tags: [
- {
- id: 1,
- taggable: {
- type: 'employee',
- employee: {
- id: 42
- }
- }
- },
- {
- id: 5,
- taggable: {
- type: 'picture',
- picture: {
- id: 1
- }
- }
- }
- ]
- }
- }
- assert_equal(expected, tag_serialization(:json))
- end
-
- def test_json_api_serialization
- expected =
- {
- data: {
- id: '1',
- type: 'pictures',
- attributes: {
- title: 'headshot-1.jpg'
- },
- relationships: {
- imageable: {
- data: {
- id: '42',
- type: 'employees'
- }
- }
- }
- }
- }
-
- assert_equal(expected, serialization(@picture, :json_api))
- end
- end
- end
- end
-end
diff --git a/test/adapter_test.rb b/test/adapter_test.rb
deleted file mode 100644
index c1b00d72..00000000
--- a/test/adapter_test.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- class AdapterTest < ActiveSupport::TestCase
- def setup
- profile = Profile.new
- @serializer = ProfileSerializer.new(profile)
- @adapter = ActiveModelSerializers::Adapter::Base.new(@serializer)
- end
-
- def test_serializable_hash_is_abstract_method
- assert_raises(NotImplementedError) do
- @adapter.serializable_hash(only: [:name])
- end
- end
-
- def test_serialization_options_ensures_option_is_a_hash
- adapter = Class.new(ActiveModelSerializers::Adapter::Base) do
- def serializable_hash(options = nil)
- serialization_options(options)
- end
- end.new(@serializer)
- assert_equal({}, adapter.serializable_hash(nil))
- assert_equal({}, adapter.serializable_hash({}))
- ensure
- ActiveModelSerializers::Adapter.adapter_map.delete_if { |k, _| k =~ /class/ }
- end
-
- def test_serialization_options_ensures_option_is_one_of_valid_options
- adapter = Class.new(ActiveModelSerializers::Adapter::Base) do
- def serializable_hash(options = nil)
- serialization_options(options)
- end
- end.new(@serializer)
- filtered_options = { now: :see_me, then: :not }
- valid_options = ActiveModel::Serializer::SERIALIZABLE_HASH_VALID_KEYS.each_with_object({}) do |option, result|
- result[option] = option
- end
- assert_equal(valid_options, adapter.serializable_hash(filtered_options.merge(valid_options)))
- ensure
- ActiveModelSerializers::Adapter.adapter_map.delete_if { |k, _| k =~ /class/ }
- end
-
- def test_serializer
- assert_equal @serializer, @adapter.serializer
- end
-
- def test_create_adapter
- adapter = ActiveModelSerializers::Adapter.create(@serializer)
- assert_equal ActiveModelSerializers::Adapter::Attributes, adapter.class
- end
-
- def test_create_adapter_with_override
- adapter = ActiveModelSerializers::Adapter.create(@serializer, adapter: :json_api)
- assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter.class
- end
-
- def test_inflected_adapter_class_for_known_adapter
- ActiveSupport::Inflector.inflections(:en) { |inflect| inflect.acronym 'API' }
- klass = ActiveModelSerializers::Adapter.adapter_class(:json_api)
-
- ActiveSupport::Inflector.inflections.acronyms.clear
-
- assert_equal ActiveModelSerializers::Adapter::JsonApi, klass
- end
- end
-end
diff --git a/test/array_serializer_test.rb b/test/array_serializer_test.rb
deleted file mode 100644
index 2ad55324..00000000
--- a/test/array_serializer_test.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'test_helper'
-require_relative 'collection_serializer_test'
-
-module ActiveModel
- class Serializer
- class ArraySerializerTest < CollectionSerializerTest
- extend Minitest::Assertions
- def self.run_one_method(*)
- _, stderr = capture_io do
- super
- end
- if stderr !~ /NOTE: ActiveModel::Serializer::ArraySerializer.new is deprecated/
- fail Minitest::Assertion, stderr
- end
- end
-
- def collection_serializer
- ArraySerializer
- end
- end
- end
-end
diff --git a/test/benchmark/app.rb b/test/benchmark/app.rb
deleted file mode 100644
index c39e9b4e..00000000
--- a/test/benchmark/app.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# https://github.com/rails-api/active_model_serializers/pull/872
-# approx ref 792fb8a9053f8db3c562dae4f40907a582dd1720 to test against
-require 'bundler/setup'
-
-require 'rails'
-require 'active_model'
-require 'active_support'
-require 'active_support/json'
-require 'action_controller'
-require 'action_controller/test_case'
-require 'action_controller/railtie'
-abort "Rails application already defined: #{Rails.application.class}" if Rails.application
-
-class NullLogger < Logger
- def initialize(*_args)
- end
-
- def add(*_args, &_block)
- end
-end
-class BenchmarkLogger < ActiveSupport::Logger
- def initialize
- @file = StringIO.new
- super(@file)
- end
-
- def messages
- @file.rewind
- @file.read
- end
-end
-# ref: https://gist.github.com/bf4/8744473
-class BenchmarkApp < Rails::Application
- # Set up production configuration
- config.eager_load = true
- config.cache_classes = true
- # CONFIG: CACHE_ON={on,off}
- config.action_controller.perform_caching = ENV['CACHE_ON'] != 'off'
- config.action_controller.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
-
- config.active_support.test_order = :random
- config.secret_token = 'S' * 30
- config.secret_key_base = 'abc123'
- config.consider_all_requests_local = false
-
- # otherwise deadlock occurred
- config.middleware.delete 'Rack::Lock'
-
- # to disable log files
- config.logger = NullLogger.new
- config.active_support.deprecation = :log
- config.log_level = :info
-end
-
-require 'active_model_serializers'
-
-# Initialize app before any serializers are defined, for running across revisions.
-# ref: https://github.com/rails-api/active_model_serializers/pull/1478
-Rails.application.initialize!
-# HACK: Serializer::cache depends on the ActionController-dependent configs being set.
-ActiveSupport.on_load(:action_controller) do
- require_relative 'fixtures'
-end
-
-require_relative 'controllers'
diff --git a/test/benchmark/benchmarking_support.rb b/test/benchmark/benchmarking_support.rb
deleted file mode 100644
index dd27f6c5..00000000
--- a/test/benchmark/benchmarking_support.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-require 'benchmark/ips'
-require 'json'
-
-# Add benchmarking runner from ruby-bench-suite
-# https://github.com/ruby-bench/ruby-bench-suite/blob/master/rails/benchmarks/support/benchmark_rails.rb
-module Benchmark
- module ActiveModelSerializers
- module TestMethods
- def request(method, path)
- response = Rack::MockRequest.new(BenchmarkApp).send(method, path)
- if response.status.in?([404, 500])
- fail "omg, #{method}, #{path}, '#{response.status}', '#{response.body}'"
- end
- response
- end
- end
-
- # extend Benchmark with an `ams` method
- def ams(label = nil, time:, disable_gc: true, warmup: 3, &block)
- fail ArgumentError.new, 'block should be passed' unless block_given?
-
- if disable_gc
- GC.disable
- else
- GC.enable
- end
-
- report = Benchmark.ips(time, warmup, true) do |x|
- x.report(label) { yield }
- end
-
- entry = report.entries.first
-
- output = {
- label: label,
- version: ::ActiveModel::Serializer::VERSION.to_s,
- rails_version: ::Rails.version.to_s,
- iterations_per_second: entry.ips,
- iterations_per_second_standard_deviation: entry.error_percentage,
- total_allocated_objects_per_iteration: count_total_allocated_objects(&block)
- }.to_json
-
- puts output
- output
- end
-
- def count_total_allocated_objects
- if block_given?
- key =
- if RUBY_VERSION < '2.2'
- :total_allocated_object
- else
- :total_allocated_objects
- end
-
- before = GC.stat[key]
- yield
- after = GC.stat[key]
- after - before
- else
- -1
- end
- end
- end
-
- extend Benchmark::ActiveModelSerializers
-end
diff --git a/test/benchmark/bm_active_record.rb b/test/benchmark/bm_active_record.rb
deleted file mode 100644
index 0837e266..00000000
--- a/test/benchmark/bm_active_record.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-require_relative './benchmarking_support'
-require_relative './app'
-
-time = 10
-disable_gc = true
-
-# This is to disable any key transform effects that may impact performance
-ActiveModelSerializers.config.key_transform = :unaltered
-
-###########################################
-# Setup active record models
-##########################################
-require 'active_record'
-require 'sqlite3'
-
-# For debugging SQL output
-# ActiveRecord::Base.logger = Logger.new(STDERR)
-
-# Change the following to reflect your database settings
-ActiveRecord::Base.establish_connection(
- adapter: 'sqlite3',
- database: ':memory:'
-)
-
-# Don't show migration output when constructing fake db
-ActiveRecord::Migration.verbose = false
-
-ActiveRecord::Schema.define do
- create_table :authors, force: true do |t|
- t.string :name
- end
-
- create_table :posts, force: true do |t|
- t.text :body
- t.string :title
- t.references :author
- end
-
- create_table :profiles, force: true do |t|
- t.text :project_url
- t.text :bio
- t.date :birthday
- t.references :author
- end
-end
-
-class Author < ActiveRecord::Base
- has_one :profile
- has_many :posts
-end
-
-class Post < ActiveRecord::Base
- belongs_to :author
-end
-
-class Profile < ActiveRecord::Base
- belongs_to :author
-end
-
-# Build out the data to serialize
-author = Author.create(name: 'Preston Sego')
-Profile.create(project_url: 'https://github.com/NullVoxPopuli', author: author)
-50.times do
- Post.create(
- body: 'something about how password restrictions are evil, and less secure, and with the math to prove it.',
- title: 'Your bank is does not know how to do security',
- author: author
- )
-end
-
-Benchmark.ams('AR: attributes', time: time, disable_gc: disable_gc) do
- ActiveModelSerializers::SerializableResource.new(author, adapter: :attributes, include: 'profile,posts').serializable_hash
-end
-
-Benchmark.ams('AR: json', time: time, disable_gc: disable_gc) do
- ActiveModelSerializers::SerializableResource.new(author, adapter: :json, include: 'profile,posts').serializable_hash
-end
-
-Benchmark.ams('AR: JSON API', time: time, disable_gc: disable_gc) do
- ActiveModelSerializers::SerializableResource.new(author, adapter: :json_api, include: 'profile,posts').serializable_hash
-end
diff --git a/test/benchmark/bm_adapter.rb b/test/benchmark/bm_adapter.rb
deleted file mode 100644
index c8bae66a..00000000
--- a/test/benchmark/bm_adapter.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-require_relative './benchmarking_support'
-require_relative './app'
-
-time = 10
-disable_gc = true
-ActiveModelSerializers.config.key_transform = :unaltered
-has_many_relationships = (0..60).map do |i|
- HasManyRelationship.new(id: i, body: 'ZOMG A HAS MANY RELATIONSHIP')
-end
-has_one_relationship = HasOneRelationship.new(
- id: 42,
- first_name: 'Joao',
- last_name: 'Moura'
-)
-primary_resource = PrimaryResource.new(
- id: 1337,
- title: 'New PrimaryResource',
- virtual_attribute: nil,
- body: 'Body',
- has_many_relationships: has_many_relationships,
- has_one_relationship: has_one_relationship
-)
-serializer = PrimaryResourceSerializer.new(primary_resource)
-
-Benchmark.ams('attributes', time: time, disable_gc: disable_gc) do
- attributes = ActiveModelSerializers::Adapter::Attributes.new(serializer)
- attributes.as_json
-end
-
-Benchmark.ams('json_api', time: time, disable_gc: disable_gc) do
- json_api = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
- json_api.as_json
-end
-
-Benchmark.ams('json', time: time, disable_gc: disable_gc) do
- json = ActiveModelSerializers::Adapter::Json.new(serializer)
- json.as_json
-end
diff --git a/test/benchmark/bm_caching.rb b/test/benchmark/bm_caching.rb
deleted file mode 100644
index ae3ad798..00000000
--- a/test/benchmark/bm_caching.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-require_relative './benchmarking_support'
-require_relative './app'
-
-# https://github.com/ruby-bench/ruby-bench-suite/blob/8ad567f7e43a044ae48c36833218423bb1e2bd9d/rails/benchmarks/actionpack_router.rb
-class ApiAssertion
- include Benchmark::ActiveModelSerializers::TestMethods
- class BadRevisionError < StandardError; end
-
- def valid?
- caching = get_caching
- caching[:body].delete('meta')
- non_caching = get_non_caching
- non_caching[:body].delete('meta')
- assert_responses(caching, non_caching)
- rescue BadRevisionError => e
- msg = { error: e.message }
- STDERR.puts msg
- STDOUT.puts msg
- exit 1
- end
-
- def get_status(on_off = 'on'.freeze)
- get("/status/#{on_off}")
- end
-
- def clear
- get('/clear')
- end
-
- def get_caching(on_off = 'on'.freeze)
- get("/caching/#{on_off}")
- end
-
- def get_fragment_caching(on_off = 'on'.freeze)
- get("/fragment_caching/#{on_off}")
- end
-
- def get_non_caching(on_off = 'on'.freeze)
- get("/non_caching/#{on_off}")
- end
-
- def debug(msg = '')
- if block_given? && ENV['DEBUG'] =~ /\Atrue|on|0\z/i
- STDERR.puts yield
- else
- STDERR.puts msg
- end
- end
-
- private
-
- def assert_responses(caching, non_caching)
- assert_equal(caching[:code], 200, "Caching response failed: #{caching}")
- assert_equal(caching[:body], expected, "Caching response format failed: \n+ #{caching[:body]}\n- #{expected}")
- assert_equal(caching[:content_type], 'application/json; charset=utf-8', "Caching response content type failed: \n+ #{caching[:content_type]}\n- application/json")
- assert_equal(non_caching[:code], 200, "Non caching response failed: #{non_caching}")
- assert_equal(non_caching[:body], expected, "Non Caching response format failed: \n+ #{non_caching[:body]}\n- #{expected}")
- assert_equal(non_caching[:content_type], 'application/json; charset=utf-8', "Non caching response content type failed: \n+ #{non_caching[:content_type]}\n- application/json")
- end
-
- def get(url)
- response = request(:get, url)
- { code: response.status, body: JSON.load(response.body), content_type: response.content_type }
- end
-
- def expected
- @expected ||=
- {
- 'primary_resource' => {
- 'id' => 1337,
- 'title' => 'New PrimaryResource',
- 'body' => 'Body',
- 'virtual_attribute' => {
- 'id' => 999,
- 'name' => 'Free-Range Virtual Attribute'
- },
- 'has_one_relationship' => {
- 'id' => 42,
- 'first_name' => 'Joao',
- 'last_name' => 'Moura'
- },
- 'has_many_relationships' => [
- {
- 'id' => 1,
- 'body' => 'ZOMG A HAS MANY RELATIONSHIP'
- }
- ]
- }
- }
- end
-
- def assert_equal(expected, actual, message)
- return true if expected == actual
- if ENV['FAIL_ASSERTION'] =~ /\Atrue|on|0\z/i # rubocop:disable Style/GuardClause
- fail BadRevisionError, message
- else
- STDERR.puts message unless ENV['SUMMARIZE']
- end
- end
-end
-assertion = ApiAssertion.new
-assertion.valid?
-assertion.debug { assertion.get_status }
-
-time = 10
-{
- 'caching on: caching serializers: gc off' => { disable_gc: true, send: [:get_caching, 'on'] },
- 'caching on: fragment caching serializers: gc off' => { disable_gc: true, send: [:get_fragment_caching, 'on'] },
- 'caching on: non-caching serializers: gc off' => { disable_gc: true, send: [:get_non_caching, 'on'] },
- 'caching off: caching serializers: gc off' => { disable_gc: true, send: [:get_caching, 'off'] },
- 'caching off: fragment caching serializers: gc off' => { disable_gc: true, send: [:get_fragment_caching, 'off'] },
- 'caching off: non-caching serializers: gc off' => { disable_gc: true, send: [:get_non_caching, 'off'] }
-}.each do |label, options|
- assertion.clear
- Benchmark.ams(label, time: time, disable_gc: options[:disable_gc]) do
- assertion.send(*options[:send])
- end
- assertion.debug { assertion.get_status(options[:send][-1]) }
-end
diff --git a/test/benchmark/bm_lookup_chain.rb b/test/benchmark/bm_lookup_chain.rb
deleted file mode 100644
index 3b32727f..00000000
--- a/test/benchmark/bm_lookup_chain.rb
+++ /dev/null
@@ -1,83 +0,0 @@
-require_relative './benchmarking_support'
-require_relative './app'
-
-time = 10
-disable_gc = true
-ActiveModelSerializers.config.key_transform = :unaltered
-
-module AmsBench
- module Api
- module V1
- class PrimaryResourceSerializer < ActiveModel::Serializer
- attributes :title, :body
-
- has_many :has_many_relationships
- end
-
- class HasManyRelationshipSerializer < ActiveModel::Serializer
- attribute :body
- end
- end
- end
- class PrimaryResourceSerializer < ActiveModel::Serializer
- attributes :title, :body
-
- has_many :has_many_relationships
-
- class HasManyRelationshipSerializer < ActiveModel::Serializer
- attribute :body
- end
- end
-end
-
-resource = PrimaryResource.new(
- id: 1,
- title: 'title',
- body: 'body',
- has_many_relationships: [
- HasManyRelationship.new(id: 1, body: 'body1'),
- HasManyRelationship.new(id: 2, body: 'body1')
- ]
-)
-
-serialization = lambda do
- ActiveModelSerializers::SerializableResource.new(resource, serializer: AmsBench::PrimaryResourceSerializer).as_json
- ActiveModelSerializers::SerializableResource.new(resource, namespace: AmsBench::Api::V1).as_json
- ActiveModelSerializers::SerializableResource.new(resource).as_json
-end
-
-def clear_cache
- AmsBench::PrimaryResourceSerializer.serializers_cache.clear
- AmsBench::Api::V1::PrimaryResourceSerializer.serializers_cache.clear
- ActiveModel::Serializer.serializers_cache.clear
-end
-
-configurable = lambda do
- clear_cache
- Benchmark.ams('Configurable Lookup Chain', time: time, disable_gc: disable_gc, &serialization)
-end
-
-old = lambda do
- clear_cache
- module ActiveModel
- class Serializer
- def self.serializer_lookup_chain_for(klass, namespace = nil)
- chain = []
-
- resource_class_name = klass.name.demodulize
- resource_namespace = klass.name.deconstantize
- serializer_class_name = "#{resource_class_name}Serializer"
-
- chain.push("#{namespace}::#{serializer_class_name}") if namespace
- chain.push("#{name}::#{serializer_class_name}") if self != ActiveModel::Serializer
- chain.push("#{resource_namespace}::#{serializer_class_name}")
- chain
- end
- end
- end
-
- Benchmark.ams('Old Lookup Chain (v0.10)', time: time, disable_gc: disable_gc, &serialization)
-end
-
-configurable.call
-old.call
diff --git a/test/benchmark/bm_transform.rb b/test/benchmark/bm_transform.rb
deleted file mode 100644
index 97c655c0..00000000
--- a/test/benchmark/bm_transform.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require_relative './benchmarking_support'
-require_relative './app'
-
-time = 10
-disable_gc = true
-ActiveModelSerializers.config.key_transform = :unaltered
-has_many_relationships = (0..50).map do |i|
- HasManyRelationship.new(id: i, body: 'ZOMG A HAS MANY RELATIONSHIP')
-end
-has_one_relationship = HasOneRelationship.new(
- id: 42,
- first_name: 'Joao',
- last_name: 'Moura'
-)
-primary_resource = PrimaryResource.new(
- id: 1337,
- title: 'New PrimaryResource',
- virtual_attribute: nil,
- body: 'Body',
- has_many_relationships: has_many_relationships,
- has_one_relationship: has_one_relationship
-)
-serializer = PrimaryResourceSerializer.new(primary_resource)
-adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
-serialization = adapter.as_json
-
-Benchmark.ams('camel', time: time, disable_gc: disable_gc) do
- CaseTransform.camel(serialization)
-end
-
-Benchmark.ams('camel_lower', time: time, disable_gc: disable_gc) do
- CaseTransform.camel_lower(serialization)
-end
-
-Benchmark.ams('dash', time: time, disable_gc: disable_gc) do
- CaseTransform.dash(serialization)
-end
-
-Benchmark.ams('unaltered', time: time, disable_gc: disable_gc) do
- CaseTransform.unaltered(serialization)
-end
-
-Benchmark.ams('underscore', time: time, disable_gc: disable_gc) do
- CaseTransform.underscore(serialization)
-end
diff --git a/test/benchmark/config.ru b/test/benchmark/config.ru
deleted file mode 100644
index 908eb28c..00000000
--- a/test/benchmark/config.ru
+++ /dev/null
@@ -1,3 +0,0 @@
-require File.expand_path(['..', 'app'].join(File::SEPARATOR), __FILE__)
-
-run Rails.application
diff --git a/test/benchmark/controllers.rb b/test/benchmark/controllers.rb
deleted file mode 100644
index 81108445..00000000
--- a/test/benchmark/controllers.rb
+++ /dev/null
@@ -1,83 +0,0 @@
-class PrimaryResourceController < ActionController::Base
- PRIMARY_RESOURCE =
- begin
- if ENV['BENCH_STRESS']
- has_many_relationships = (0..50).map do |i|
- HasManyRelationship.new(id: i, body: 'ZOMG A HAS MANY RELATIONSHIP')
- end
- else
- has_many_relationships = [HasManyRelationship.new(id: 1, body: 'ZOMG A HAS MANY RELATIONSHIP')]
- end
- has_one_relationship = HasOneRelationship.new(id: 42, first_name: 'Joao', last_name: 'Moura')
- PrimaryResource.new(id: 1337, title: 'New PrimaryResource', virtual_attribute: nil, body: 'Body', has_many_relationships: has_many_relationships, has_one_relationship: has_one_relationship)
- end
-
- def render_with_caching_serializer
- toggle_cache_status
- render json: PRIMARY_RESOURCE, serializer: CachingPrimaryResourceSerializer, adapter: :json, meta: { caching: perform_caching }
- end
-
- def render_with_fragment_caching_serializer
- toggle_cache_status
- render json: PRIMARY_RESOURCE, serializer: FragmentCachingPrimaryResourceSerializer, adapter: :json, meta: { caching: perform_caching }
- end
-
- def render_with_non_caching_serializer
- toggle_cache_status
- render json: PRIMARY_RESOURCE, adapter: :json, meta: { caching: perform_caching }
- end
-
- def render_cache_status
- toggle_cache_status
- # Uncomment to debug
- # STDERR.puts cache_store.class
- # STDERR.puts cache_dependencies
- # ActiveSupport::Cache::Store.logger.debug [ActiveModelSerializers.config.cache_store, ActiveModelSerializers.config.perform_caching, CachingPrimaryResourceSerializer._cache, perform_caching, params].inspect
- render json: { caching: perform_caching, meta: { cache_log: cache_messages, cache_status: cache_status } }.to_json
- end
-
- def clear
- ActionController::Base.cache_store.clear
- # Test caching is on
- # Uncomment to turn on logger; possible performance issue
- # logger = BenchmarkLogger.new
- # ActiveSupport::Cache::Store.logger = logger # seems to be the best way
- #
- # the below is used in some rails tests but isn't available/working in all versions, so far as I can tell
- # https://github.com/rails/rails/pull/15943
- # ActiveSupport::Notifications.subscribe(/^cache_(.*)\.active_support$/) do |*args|
- # logger.debug ActiveSupport::Notifications::Event.new(*args)
- # end
- render json: 'ok'.to_json
- end
-
- private
-
- def cache_status
- {
- controller: perform_caching,
- app: Rails.configuration.action_controller.perform_caching,
- serializers: Rails.configuration.serializers.each_with_object({}) { |serializer, data| data[serializer.name] = serializer._cache.present? }
- }
- end
-
- def cache_messages
- ActiveSupport::Cache::Store.logger.is_a?(BenchmarkLogger) && ActiveSupport::Cache::Store.logger.messages.split("\n")
- end
-
- def toggle_cache_status
- case params[:on]
- when 'on'.freeze then self.perform_caching = true
- when 'off'.freeze then self.perform_caching = false
- else nil # no-op
- end
- end
-end
-
-Rails.application.routes.draw do
- get '/status(/:on)' => 'primary_resource#render_cache_status'
- get '/clear' => 'primary_resource#clear'
- get '/caching(/:on)' => 'primary_resource#render_with_caching_serializer'
- get '/fragment_caching(/:on)' => 'primary_resource#render_with_fragment_caching_serializer'
- get '/non_caching(/:on)' => 'primary_resource#render_with_non_caching_serializer'
-end
diff --git a/test/benchmark/fixtures.rb b/test/benchmark/fixtures.rb
deleted file mode 100644
index c91e102d..00000000
--- a/test/benchmark/fixtures.rb
+++ /dev/null
@@ -1,219 +0,0 @@
-Rails.configuration.serializers = []
-class HasOneRelationshipSerializer < ActiveModel::Serializer
- attributes :id, :first_name, :last_name
-
- has_many :primary_resources, embed: :ids
- has_one :bio
-end
-Rails.configuration.serializers << HasOneRelationshipSerializer
-
-class VirtualAttributeSerializer < ActiveModel::Serializer
- attributes :id, :name
-end
-Rails.configuration.serializers << VirtualAttributeSerializer
-
-class HasManyRelationshipSerializer < ActiveModel::Serializer
- attributes :id, :body
-
- belongs_to :primary_resource
- belongs_to :has_one_relationship
-end
-Rails.configuration.serializers << HasManyRelationshipSerializer
-
-class PrimaryResourceSerializer < ActiveModel::Serializer
- attributes :id, :title, :body
-
- has_many :has_many_relationships, serializer: HasManyRelationshipSerializer
- belongs_to :virtual_attribute, serializer: VirtualAttributeSerializer
- belongs_to :has_one_relationship, serializer: HasOneRelationshipSerializer
-
- link(:primary_resource_has_one_relationships) { 'https://example.com/primary_resource_has_one_relationships' }
-
- meta do
- {
- rating: 5,
- favorite_count: 10
- }
- end
-
- def virtual_attribute
- VirtualAttribute.new(id: 999, name: 'Free-Range Virtual Attribute')
- end
-end
-Rails.configuration.serializers << PrimaryResourceSerializer
-
-class CachingHasOneRelationshipSerializer < HasOneRelationshipSerializer
- cache key: 'writer', skip_digest: true
-end
-Rails.configuration.serializers << CachingHasOneRelationshipSerializer
-
-class CachingHasManyRelationshipSerializer < HasManyRelationshipSerializer
- cache expires_in: 1.day, skip_digest: true
-end
-Rails.configuration.serializers << CachingHasManyRelationshipSerializer
-
-# see https://github.com/rails-api/active_model_serializers/pull/1690/commits/68715b8f99bc29677e8a47bb3f305f23c077024b#r60344532
-class CachingPrimaryResourceSerializer < ActiveModel::Serializer
- cache key: 'primary_resource', expires_in: 0.1, skip_digest: true
-
- attributes :id, :title, :body
-
- belongs_to :virtual_attribute, serializer: VirtualAttributeSerializer
- belongs_to :has_one_relationship, serializer: CachingHasOneRelationshipSerializer
- has_many :has_many_relationships, serializer: CachingHasManyRelationshipSerializer
-
- link(:primary_resource_has_one_relationships) { 'https://example.com/primary_resource_has_one_relationships' }
-
- meta do
- {
- rating: 5,
- favorite_count: 10
- }
- end
-
- def virtual_attribute
- VirtualAttribute.new(id: 999, name: 'Free-Range Virtual Attribute')
- end
-end
-Rails.configuration.serializers << CachingPrimaryResourceSerializer
-
-class FragmentCachingHasOneRelationshipSerializer < HasOneRelationshipSerializer
- cache key: 'writer', only: [:first_name, :last_name], skip_digest: true
-end
-Rails.configuration.serializers << FragmentCachingHasOneRelationshipSerializer
-
-class FragmentCachingHasManyRelationshipSerializer < HasManyRelationshipSerializer
- cache expires_in: 1.day, except: [:body], skip_digest: true
-end
-Rails.configuration.serializers << CachingHasManyRelationshipSerializer
-
-# see https://github.com/rails-api/active_model_serializers/pull/1690/commits/68715b8f99bc29677e8a47bb3f305f23c077024b#r60344532
-class FragmentCachingPrimaryResourceSerializer < ActiveModel::Serializer
- cache key: 'primary_resource', expires_in: 0.1, skip_digest: true
-
- attributes :id, :title, :body
-
- belongs_to :virtual_attribute, serializer: VirtualAttributeSerializer
- belongs_to :has_one_relationship, serializer: FragmentCachingHasOneRelationshipSerializer
- has_many :has_many_relationships, serializer: FragmentCachingHasManyRelationshipSerializer
-
- link(:primary_resource_has_one_relationships) { 'https://example.com/primary_resource_has_one_relationships' }
-
- meta do
- {
- rating: 5,
- favorite_count: 10
- }
- end
-
- def virtual_attribute
- VirtualAttribute.new(id: 999, name: 'Free-Range Virtual Attribute')
- end
-end
-Rails.configuration.serializers << FragmentCachingPrimaryResourceSerializer
-
-if ENV['ENABLE_ACTIVE_RECORD'] == 'true'
- require 'active_record'
-
- ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
- ActiveRecord::Schema.define do
- self.verbose = false
-
- create_table :virtual_attributes, force: true do |t|
- t.string :name
- t.timestamps null: false
- end
- create_table :has_one_relationships, force: true do |t|
- t.string :first_name
- t.string :last_name
- t.timestamps null: false
- end
- create_table :primary_resources, force: true do |t|
- t.string :title
- t.text :body
- t.references :has_one_relationship
- t.references :virtual_attribute
- t.timestamps null: false
- end
- create_table :has_many_relationships, force: true do |t|
- t.text :body
- t.references :has_one_relationship
- t.references :primary_resource
- t.timestamps null: false
- end
- end
-
- class HasManyRelationship < ActiveRecord::Base
- belongs_to :has_one_relationship
- belongs_to :primary_resource
- end
-
- class HasOneRelationship < ActiveRecord::Base
- has_many :primary_resources
- has_many :has_many_relationships
- end
-
- class PrimaryResource < ActiveRecord::Base
- has_many :has_many_relationships
- belongs_to :has_one_relationship
- belongs_to :virtual_attribute
- end
-
- class VirtualAttribute < ActiveRecord::Base
- has_many :primary_resources
- end
-else
- # ActiveModelSerializers::Model is a convenient
- # serializable class to inherit from when making
- # serializable non-activerecord objects.
- class BenchmarkModel
- include ActiveModel::Model
- include ActiveModel::Serializers::JSON
-
- attr_reader :attributes
-
- def initialize(attributes = {})
- @attributes = attributes
- super
- end
-
- # Defaults to the downcased model name.
- def id
- attributes.fetch(:id) { self.class.name.downcase }
- end
-
- # Defaults to the downcased model name and updated_at
- def cache_key
- attributes.fetch(:cache_key) { "#{self.class.name.downcase}/#{id}" }
- end
-
- # Defaults to the time the serializer file was modified.
- def updated_at
- @updated_at ||= attributes.fetch(:updated_at) { File.mtime(__FILE__) }
- end
-
- def read_attribute_for_serialization(key)
- if key == :id || key == 'id'
- attributes.fetch(key) { id }
- else
- attributes[key]
- end
- end
- end
-
- class HasManyRelationship < BenchmarkModel
- attr_accessor :id, :body
- end
-
- class HasOneRelationship < BenchmarkModel
- attr_accessor :id, :first_name, :last_name, :primary_resources
- end
-
- class PrimaryResource < BenchmarkModel
- attr_accessor :id, :title, :body, :has_many_relationships, :virtual_attribute, :has_one_relationship
- end
-
- class VirtualAttribute < BenchmarkModel
- attr_accessor :id, :name
- end
-end
diff --git a/test/cache_test.rb b/test/cache_test.rb
deleted file mode 100644
index f0958931..00000000
--- a/test/cache_test.rb
+++ /dev/null
@@ -1,651 +0,0 @@
-require 'test_helper'
-require 'tmpdir'
-require 'tempfile'
-
-module ActiveModelSerializers
- class CacheTest < ActiveSupport::TestCase
- class Article < ::Model
- attributes :title
- # To confirm error is raised when cache_key is not set and cache_key option not passed to cache
- undef_method :cache_key
- end
- class ArticleSerializer < ActiveModel::Serializer
- cache only: [:place], skip_digest: true
- attributes :title
- end
-
- class Author < ::Model
- attributes :id, :name
- associations :posts, :bio, :roles
- end
- # Instead of a primitive cache key (i.e. a string), this class
- # returns a list of objects that require to be expanded themselves.
- class AuthorWithExpandableCacheElements < Author
- # For the test purposes it's important that #to_s for HasCacheKey differs
- # between instances, hence not a Struct.
- class HasCacheKey
- attr_reader :cache_key
- def initialize(cache_key)
- @cache_key = cache_key
- end
-
- def to_s
- "HasCacheKey##{object_id}"
- end
- end
-
- def cache_key
- [
- HasCacheKey.new(name),
- HasCacheKey.new(id)
- ]
- end
- end
- class UncachedAuthor < Author
- # To confirm cache_key is set using updated_at and cache_key option passed to cache
- undef_method :cache_key
- end
- class AuthorSerializer < ActiveModel::Serializer
- cache key: 'writer', skip_digest: true
- attributes :id, :name
-
- has_many :posts
- has_many :roles
- has_one :bio
- end
-
- class Blog < ::Model
- attributes :name
- associations :writer
- end
- class BlogSerializer < ActiveModel::Serializer
- cache key: 'blog'
- attributes :id, :name
-
- belongs_to :writer
- end
-
- class Comment < ::Model
- attributes :id, :body
- associations :post, :author
-
- # Uses a custom non-time-based cache key
- def cache_key
- "comment/#{id}"
- end
- end
- class CommentSerializer < ActiveModel::Serializer
- cache expires_in: 1.day, skip_digest: true
- attributes :id, :body
- belongs_to :post
- belongs_to :author
- end
-
- class Post < ::Model
- attributes :id, :title, :body
- associations :author, :comments, :blog
- end
- class PostSerializer < ActiveModel::Serializer
- cache key: 'post', expires_in: 0.1, skip_digest: true
- attributes :id, :title, :body
-
- has_many :comments
- belongs_to :blog
- belongs_to :author
- end
-
- class Role < ::Model
- attributes :name, :description, :special_attribute
- associations :author
- end
- class RoleSerializer < ActiveModel::Serializer
- cache only: [:name, :slug], skip_digest: true
- attributes :id, :name, :description
- attribute :friendly_id, key: :slug
- belongs_to :author
-
- def friendly_id
- "#{object.name}-#{object.id}"
- end
- end
- class InheritedRoleSerializer < RoleSerializer
- cache key: 'inherited_role', only: [:name, :special_attribute]
- attribute :special_attribute
- end
-
- setup do
- cache_store.clear
- @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @post = Post.new(id: 'post', title: 'New Post', body: 'Body')
- @bio = Bio.new(id: 1, content: 'AMS Contributor')
- @author = Author.new(id: 'author', name: 'Joao M. D. Moura')
- @blog = Blog.new(id: 999, name: 'Custom blog', writer: @author)
- @role = Role.new(name: 'Great Author')
- @location = Location.new(lat: '-23.550520', lng: '-46.633309')
- @place = Place.new(name: 'Amazing Place')
- @author.posts = [@post]
- @author.roles = [@role]
- @role.author = @author
- @author.bio = @bio
- @bio.author = @author
- @post.comments = [@comment]
- @post.author = @author
- @comment.post = @post
- @comment.author = @author
- @post.blog = @blog
- @location.place = @place
-
- @location_serializer = LocationSerializer.new(@location)
- @bio_serializer = BioSerializer.new(@bio)
- @role_serializer = RoleSerializer.new(@role)
- @post_serializer = PostSerializer.new(@post)
- @author_serializer = AuthorSerializer.new(@author)
- @comment_serializer = CommentSerializer.new(@comment)
- @blog_serializer = BlogSerializer.new(@blog)
- end
-
- def test_explicit_cache_store
- default_store = Class.new(ActiveModel::Serializer) do
- cache
- end
- explicit_store = Class.new(ActiveModel::Serializer) do
- cache cache_store: ActiveSupport::Cache::FileStore
- end
-
- assert ActiveSupport::Cache::MemoryStore, ActiveModelSerializers.config.cache_store
- assert ActiveSupport::Cache::MemoryStore, default_store.cache_store
- assert ActiveSupport::Cache::FileStore, explicit_store.cache_store
- end
-
- def test_inherited_cache_configuration
- inherited_serializer = Class.new(PostSerializer)
-
- assert_equal PostSerializer._cache_key, inherited_serializer._cache_key
- assert_equal PostSerializer._cache_options, inherited_serializer._cache_options
- end
-
- def test_override_cache_configuration
- inherited_serializer = Class.new(PostSerializer) do
- cache key: 'new-key'
- end
-
- assert_equal PostSerializer._cache_key, 'post'
- assert_equal inherited_serializer._cache_key, 'new-key'
- end
-
- def test_cache_definition
- assert_equal(cache_store, @post_serializer.class._cache)
- assert_equal(cache_store, @author_serializer.class._cache)
- assert_equal(cache_store, @comment_serializer.class._cache)
- end
-
- def test_cache_key_definition
- assert_equal('post', @post_serializer.class._cache_key)
- assert_equal('writer', @author_serializer.class._cache_key)
- assert_nil(@comment_serializer.class._cache_key)
- end
-
- def test_cache_key_interpolation_with_updated_at_when_cache_key_is_not_defined_on_object
- uncached_author = UncachedAuthor.new(name: 'Joao M. D. Moura')
- uncached_author_serializer = AuthorSerializer.new(uncached_author)
-
- render_object_with_cache(uncached_author)
- key = "#{uncached_author_serializer.class._cache_key}/#{uncached_author_serializer.object.id}-#{uncached_author_serializer.object.updated_at.strftime('%Y%m%d%H%M%S%9N')}"
- key = "#{key}/#{adapter.cache_key}"
- assert_equal(uncached_author_serializer.attributes.to_json, cache_store.fetch(key).to_json)
- end
-
- def test_cache_key_expansion
- author = AuthorWithExpandableCacheElements.new(id: 10, name: 'hello')
- same_author = AuthorWithExpandableCacheElements.new(id: 10, name: 'hello')
- diff_author = AuthorWithExpandableCacheElements.new(id: 11, name: 'hello')
-
- author_serializer = AuthorSerializer.new(author)
- same_author_serializer = AuthorSerializer.new(same_author)
- diff_author_serializer = AuthorSerializer.new(diff_author)
- adapter = AuthorSerializer.serialization_adapter_instance
-
- assert_equal(author_serializer.cache_key(adapter), same_author_serializer.cache_key(adapter))
- refute_equal(author_serializer.cache_key(adapter), diff_author_serializer.cache_key(adapter))
- end
-
- def test_default_cache_key_fallback
- render_object_with_cache(@comment)
- key = "#{@comment.cache_key}/#{adapter.cache_key}"
- assert_equal(@comment_serializer.attributes.to_json, cache_store.fetch(key).to_json)
- end
-
- def test_error_is_raised_if_cache_key_is_not_defined_on_object_or_passed_as_cache_option
- article = Article.new(title: 'Must Read')
- e = assert_raises ActiveModel::Serializer::UndefinedCacheKey do
- render_object_with_cache(article)
- end
- assert_match(/ActiveModelSerializers::CacheTest::Article must define #cache_key, or the 'key:' option must be passed into 'ActiveModelSerializers::CacheTest::ArticleSerializer.cache'/, e.message)
- end
-
- def test_cache_options_definition
- assert_equal({ expires_in: 0.1, skip_digest: true }, @post_serializer.class._cache_options)
- assert_nil(@blog_serializer.class._cache_options)
- assert_equal({ expires_in: 1.day, skip_digest: true }, @comment_serializer.class._cache_options)
- end
-
- def test_fragment_cache_definition
- assert_equal([:name, :slug], @role_serializer.class._cache_only)
- assert_equal([:content], @bio_serializer.class._cache_except)
- end
-
- def test_associations_separately_cache
- cache_store.clear
- assert_nil(cache_store.fetch(@post.cache_key))
- assert_nil(cache_store.fetch(@comment.cache_key))
-
- Timecop.freeze(Time.current) do
- render_object_with_cache(@post)
-
- key = "#{@post.cache_key}/#{adapter.cache_key}"
- assert_equal(@post_serializer.attributes, cache_store.fetch(key))
- key = "#{@comment.cache_key}/#{adapter.cache_key}"
- assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
- end
- end
-
- def test_associations_cache_when_updated
- Timecop.freeze(Time.current) do
- # Generate a new Cache of Post object and each objects related to it.
- render_object_with_cache(@post)
-
- # Check if it cached the objects separately
- key = "#{@post.cache_key}/#{adapter.cache_key}"
- assert_equal(@post_serializer.attributes, cache_store.fetch(key))
- key = "#{@comment.cache_key}/#{adapter.cache_key}"
- assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
-
- # Simulating update on comments relationship with Post
- new_comment = Comment.new(id: 2567, body: 'ZOMG A NEW COMMENT')
- new_comment_serializer = CommentSerializer.new(new_comment)
- @post.comments = [new_comment]
-
- # Ask for the serialized object
- render_object_with_cache(@post)
-
- # Check if the the new comment was cached
- key = "#{new_comment.cache_key}/#{adapter.cache_key}"
- assert_equal(new_comment_serializer.attributes, cache_store.fetch(key))
- key = "#{@post.cache_key}/#{adapter.cache_key}"
- assert_equal(@post_serializer.attributes, cache_store.fetch(key))
- end
- end
-
- def test_fragment_fetch_with_virtual_associations
- expected_result = {
- id: @location.id,
- lat: @location.lat,
- lng: @location.lng,
- address: 'Nowhere'
- }
-
- hash = render_object_with_cache(@location)
-
- assert_equal(hash, expected_result)
- key = "#{@location.cache_key}/#{adapter.cache_key}"
- assert_equal({ address: 'Nowhere' }, cache_store.fetch(key))
- end
-
- def test_fragment_cache_with_inheritance
- inherited = render_object_with_cache(@role, serializer: InheritedRoleSerializer)
- base = render_object_with_cache(@role)
-
- assert_includes(inherited.keys, :special_attribute)
- refute_includes(base.keys, :special_attribute)
- end
-
- def test_uses_adapter_in_cache_key
- render_object_with_cache(@post)
- key = "#{@post.cache_key}/#{adapter.class.to_s.demodulize.underscore}"
- assert_equal(@post_serializer.attributes, cache_store.fetch(key))
- end
-
- # Based on original failing test by @kevintyll
- # rubocop:disable Metrics/AbcSize
- def test_a_serializer_rendered_by_two_adapter_returns_differently_fetch_attributes
- Object.const_set(:Alert, Class.new(ActiveModelSerializers::Model) do
- attributes :id, :status, :resource, :started_at, :ended_at, :updated_at, :created_at
- end)
- Object.const_set(:UncachedAlertSerializer, Class.new(ActiveModel::Serializer) do
- attributes :id, :status, :resource, :started_at, :ended_at, :updated_at, :created_at
- end)
- Object.const_set(:AlertSerializer, Class.new(UncachedAlertSerializer) do
- cache
- end)
-
- alert = Alert.new(
- id: 1,
- status: 'fail',
- resource: 'resource-1',
- started_at: Time.new(2016, 3, 31, 21, 36, 35, 0),
- ended_at: nil,
- updated_at: Time.new(2016, 3, 31, 21, 27, 35, 0),
- created_at: Time.new(2016, 3, 31, 21, 37, 35, 0)
- )
-
- expected_fetch_attributes = {
- id: 1,
- status: 'fail',
- resource: 'resource-1',
- started_at: alert.started_at,
- ended_at: nil,
- updated_at: alert.updated_at,
- created_at: alert.created_at
- }.with_indifferent_access
- expected_cached_jsonapi_attributes = {
- id: '1',
- type: 'alerts',
- attributes: {
- status: 'fail',
- resource: 'resource-1',
- started_at: alert.started_at,
- ended_at: nil,
- updated_at: alert.updated_at,
- created_at: alert.created_at
- }
- }.with_indifferent_access
-
- # Assert attributes are serialized correctly
- serializable_alert = serializable(alert, serializer: AlertSerializer, adapter: :attributes)
- attributes_serialization = serializable_alert.as_json.with_indifferent_access
- assert_equal expected_fetch_attributes, alert.attributes
- assert_equal alert.attributes, attributes_serialization
- attributes_cache_key = serializable_alert.adapter.serializer.cache_key(serializable_alert.adapter)
- assert_equal attributes_serialization, cache_store.fetch(attributes_cache_key).with_indifferent_access
-
- serializable_alert = serializable(alert, serializer: AlertSerializer, adapter: :json_api)
- jsonapi_cache_key = serializable_alert.adapter.serializer.cache_key(serializable_alert.adapter)
- # Assert cache keys differ
- refute_equal attributes_cache_key, jsonapi_cache_key
- # Assert (cached) serializations differ
- jsonapi_serialization = serializable_alert.as_json
- assert_equal alert.status, jsonapi_serialization.fetch(:data).fetch(:attributes).fetch(:status)
- serializable_alert = serializable(alert, serializer: UncachedAlertSerializer, adapter: :json_api)
- assert_equal serializable_alert.as_json, jsonapi_serialization
-
- cached_serialization = cache_store.fetch(jsonapi_cache_key).with_indifferent_access
- assert_equal expected_cached_jsonapi_attributes, cached_serialization
- ensure
- Object.send(:remove_const, :Alert)
- Object.send(:remove_const, :AlertSerializer)
- Object.send(:remove_const, :UncachedAlertSerializer)
- end
- # rubocop:enable Metrics/AbcSize
-
- def test_uses_file_digest_in_cache_key
- render_object_with_cache(@blog)
- file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
- key = "#{@blog.cache_key}/#{adapter.cache_key}/#{file_digest}"
- assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
- end
-
- def test_cache_digest_definition
- file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
- assert_equal(file_digest, @post_serializer.class._cache_digest)
- end
-
- def test_object_cache_keys
- serializable = ActiveModelSerializers::SerializableResource.new([@comment, @comment])
- include_directive = JSONAPI::IncludeDirective.new('*', allow_wildcard: true)
-
- actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter, include_directive)
-
- assert_equal 3, actual.size
- expected_key = "comment/1/#{serializable.adapter.cache_key}"
- assert actual.any? { |key| key == expected_key }, "actual '#{actual}' should include #{expected_key}"
- expected_key = %r{post/post-\d+}
- assert actual.any? { |key| key =~ expected_key }, "actual '#{actual}' should match '#{expected_key}'"
- expected_key = %r{author/author-\d+}
- assert actual.any? { |key| key =~ expected_key }, "actual '#{actual}' should match '#{expected_key}'"
- end
-
- # rubocop:disable Metrics/AbcSize
- def test_fetch_attributes_from_cache
- serializers = ActiveModel::Serializer::CollectionSerializer.new([@comment, @comment])
-
- Timecop.freeze(Time.current) do
- render_object_with_cache(@comment)
-
- options = {}
- adapter_options = {}
- adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
- serializers.serializable_hash(adapter_options, options, adapter_instance)
- cached_attributes = adapter_options.fetch(:cached_attributes).with_indifferent_access
-
- include_directive = ActiveModelSerializers.default_include_directive
- manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive).with_indifferent_access
- assert_equal manual_cached_attributes, cached_attributes
-
- assert_equal cached_attributes["#{@comment.cache_key}/#{adapter_instance.cache_key}"], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
- assert_equal cached_attributes["#{@comment.post.cache_key}/#{adapter_instance.cache_key}"], Post.new(id: 'post', title: 'New Post', body: 'Body').attributes
-
- writer = @comment.post.blog.writer
- writer_cache_key = writer.cache_key
- assert_equal cached_attributes["#{writer_cache_key}/#{adapter_instance.cache_key}"], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
- end
- end
- # rubocop:enable Metrics/AbcSize
-
- def test_cache_read_multi_with_fragment_cache_enabled
- post_serializer = Class.new(ActiveModel::Serializer) do
- cache except: [:body]
- end
-
- serializers = ActiveModel::Serializer::CollectionSerializer.new([@post, @post], serializer: post_serializer)
-
- Timecop.freeze(Time.current) do
- # Warming up.
- options = {}
- adapter_options = {}
- adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
- serializers.serializable_hash(adapter_options, options, adapter_instance)
-
- # Should find something with read_multi now
- adapter_options = {}
- serializers.serializable_hash(adapter_options, options, adapter_instance)
- cached_attributes = adapter_options.fetch(:cached_attributes)
-
- include_directive = ActiveModelSerializers.default_include_directive
- manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive)
-
- refute_equal 0, cached_attributes.size
- refute_equal 0, manual_cached_attributes.size
- assert_equal manual_cached_attributes, cached_attributes
- end
- end
-
- def test_serializer_file_path_on_nix
- path = '/Users/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb'
- caller_line = "#{path}:1:in `'"
- assert_equal caller_line[ActiveModel::Serializer::CALLER_FILE], path
- end
-
- def test_serializer_file_path_on_windows
- path = 'c:/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb'
- caller_line = "#{path}:1:in `'"
- assert_equal caller_line[ActiveModel::Serializer::CALLER_FILE], path
- end
-
- def test_serializer_file_path_with_space
- path = '/Users/git/ember js/ember-crm-backend/app/serializers/lead_serializer.rb'
- caller_line = "#{path}:1:in `'"
- assert_equal caller_line[ActiveModel::Serializer::CALLER_FILE], path
- end
-
- def test_serializer_file_path_with_submatch
- # The submatch in the path ensures we're using a correctly greedy regexp.
- path = '/Users/git/ember js/ember:123:in x/app/serializers/lead_serializer.rb'
- caller_line = "#{path}:1:in `'"
- assert_equal caller_line[ActiveModel::Serializer::CALLER_FILE], path
- end
-
- def test_digest_caller_file
- contents = "puts 'AMS rocks'!"
- dir = Dir.mktmpdir('space char')
- file = Tempfile.new('some_ruby.rb', dir)
- file.write(contents)
- path = file.path
- caller_line = "#{path}:1:in `'"
- file.close
- assert_equal ActiveModel::Serializer.digest_caller_file(caller_line), Digest::MD5.hexdigest(contents)
- ensure
- file.unlink
- FileUtils.remove_entry dir
- end
-
- def test_warn_on_serializer_not_defined_in_file
- called = false
- serializer = Class.new(ActiveModel::Serializer)
- assert_output(nil, /_cache_digest/) do
- serializer.digest_caller_file('')
- called = true
- end
- assert called
- end
-
- def test_cached_false_without_cache_store
- cached_serializer = build_cached_serializer do |serializer|
- serializer._cache = nil
- end
- refute cached_serializer.class.cache_enabled?
- end
-
- def test_cached_true_with_cache_store_and_without_cache_only_and_cache_except
- cached_serializer = build_cached_serializer do |serializer|
- serializer._cache = Object
- end
- assert cached_serializer.class.cache_enabled?
- end
-
- def test_cached_false_with_cache_store_and_with_cache_only
- cached_serializer = build_cached_serializer do |serializer|
- serializer._cache = Object
- serializer._cache_only = [:name]
- end
- refute cached_serializer.class.cache_enabled?
- end
-
- def test_cached_false_with_cache_store_and_with_cache_except
- cached_serializer = build_cached_serializer do |serializer|
- serializer._cache = Object
- serializer._cache_except = [:content]
- end
- refute cached_serializer.class.cache_enabled?
- end
-
- def test_fragment_cached_false_without_cache_store
- cached_serializer = build_cached_serializer do |serializer|
- serializer._cache = nil
- serializer._cache_only = [:name]
- end
- refute cached_serializer.class.fragment_cache_enabled?
- end
-
- def test_fragment_cached_true_with_cache_store_and_cache_only
- cached_serializer = build_cached_serializer do |serializer|
- serializer._cache = Object
- serializer._cache_only = [:name]
- end
- assert cached_serializer.class.fragment_cache_enabled?
- end
-
- def test_fragment_cached_true_with_cache_store_and_cache_except
- cached_serializer = build_cached_serializer do |serializer|
- serializer._cache = Object
- serializer._cache_except = [:content]
- end
- assert cached_serializer.class.fragment_cache_enabled?
- end
-
- def test_fragment_cached_false_with_cache_store_and_cache_except_and_cache_only
- cached_serializer = build_cached_serializer do |serializer|
- serializer._cache = Object
- serializer._cache_except = [:content]
- serializer._cache_only = [:name]
- end
- refute cached_serializer.class.fragment_cache_enabled?
- end
-
- def test_fragment_fetch_with_virtual_attributes
- author = Author.new(name: 'Joao M. D. Moura')
- role = Role.new(name: 'Great Author', description: nil)
- role.author = [author]
- role_serializer = RoleSerializer.new(role)
- adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(role_serializer)
- expected_result = {
- id: role.id,
- description: role.description,
- slug: "#{role.name}-#{role.id}",
- name: role.name
- }
- cache_store.clear
-
- role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
- assert_equal(role_hash, expected_result)
-
- role.id = 'this has been updated'
- role.name = 'this was cached'
-
- role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
- assert_equal(expected_result.merge(id: role.id), role_hash)
- end
-
- def test_fragment_fetch_with_except
- adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@bio_serializer)
- expected_result = {
- id: @bio.id,
- rating: nil,
- content: @bio.content
- }
- cache_store.clear
-
- bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
- assert_equal(expected_result, bio_hash)
-
- @bio.content = 'this has been updated'
- @bio.rating = 'this was cached'
-
- bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
- assert_equal(expected_result.merge(content: @bio.content), bio_hash)
- end
-
- def test_fragment_fetch_with_namespaced_object
- @spam = Spam::UnrelatedLink.new(id: 'spam-id-1')
- @spam_serializer = Spam::UnrelatedLinkSerializer.new(@spam)
- adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@spam_serializer)
- @spam_hash = @spam_serializer.fetch_attributes_fragment(adapter_instance)
- expected_result = {
- id: @spam.id
- }
- assert_equal(@spam_hash, expected_result)
- end
-
- private
-
- def cache_store
- ActiveModelSerializers.config.cache_store
- end
-
- def build_cached_serializer
- serializer = Class.new(ActiveModel::Serializer)
- serializer._cache_key = nil
- serializer._cache_options = nil
- yield serializer if block_given?
- serializer.new(Object)
- end
-
- def render_object_with_cache(obj, options = {})
- @serializable_resource = serializable(obj, options)
- @serializable_resource.serializable_hash
- end
-
- def adapter
- @serializable_resource.adapter
- end
- end
-end
diff --git a/test/collection_serializer_test.rb b/test/collection_serializer_test.rb
deleted file mode 100644
index cdbebb15..00000000
--- a/test/collection_serializer_test.rb
+++ /dev/null
@@ -1,123 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class CollectionSerializerTest < ActiveSupport::TestCase
- class SingularModel < ::Model; end
- class SingularModelSerializer < ActiveModel::Serializer
- end
- class HasManyModel < ::Model
- associations :singular_models
- end
- class HasManyModelSerializer < ActiveModel::Serializer
- has_many :singular_models
-
- def custom_options
- instance_options
- end
- end
- class MessagesSerializer < ActiveModel::Serializer
- type 'messages'
- end
-
- def setup
- @singular_model = SingularModel.new
- @has_many_model = HasManyModel.new
- @resource = build_named_collection @singular_model, @has_many_model
- @serializer = collection_serializer.new(@resource, some: :options)
- end
-
- def collection_serializer
- CollectionSerializer
- end
-
- def build_named_collection(*resource)
- resource.define_singleton_method(:name) { 'MeResource' }
- resource
- end
-
- def test_has_object_reader_serializer_interface
- assert_equal @serializer.object, @resource
- end
-
- def test_respond_to_each
- assert_respond_to @serializer, :each
- end
-
- def test_each_object_should_be_serialized_with_appropriate_serializer
- serializers = @serializer.to_a
-
- assert_kind_of SingularModelSerializer, serializers.first
- assert_kind_of SingularModel, serializers.first.object
-
- assert_kind_of HasManyModelSerializer, serializers.last
- assert_kind_of HasManyModel, serializers.last.object
-
- assert_equal :options, serializers.last.custom_options[:some]
- end
-
- def test_serializer_option_not_passed_to_each_serializer
- serializers = collection_serializer.new([@has_many_model], serializer: HasManyModelSerializer).to_a
-
- refute serializers.first.custom_options.key?(:serializer)
- end
-
- def test_root_default
- @serializer = collection_serializer.new([@singular_model, @has_many_model])
- assert_nil @serializer.root
- end
-
- def test_root
- expected = 'custom_root'
- @serializer = collection_serializer.new([@singular_model, @has_many_model], root: expected)
- assert_equal expected, @serializer.root
- end
-
- def test_root_with_no_serializers
- expected = 'custom_root'
- @serializer = collection_serializer.new([], root: expected)
- assert_equal expected, @serializer.root
- end
-
- def test_json_key_with_resource_with_serializer
- singular_key = @serializer.send(:serializers).first.json_key
- assert_equal singular_key.pluralize, @serializer.json_key
- end
-
- def test_json_key_with_resource_with_name_and_no_serializers
- serializer = collection_serializer.new(build_named_collection)
- assert_equal 'me_resources', serializer.json_key
- end
-
- def test_json_key_with_resource_with_nil_name_and_no_serializers
- resource = []
- resource.define_singleton_method(:name) { nil }
- serializer = collection_serializer.new(resource)
- assert_nil serializer.json_key
- end
-
- def test_json_key_with_resource_without_name_and_no_serializers
- serializer = collection_serializer.new([])
- assert_nil serializer.json_key
- end
-
- def test_json_key_with_empty_resources_with_serializer
- resource = []
- serializer = collection_serializer.new(resource, serializer: MessagesSerializer)
- assert_equal 'messages', serializer.json_key
- end
-
- def test_json_key_with_root
- expected = 'custom_root'
- serializer = collection_serializer.new(@resource, root: expected)
- assert_equal expected, serializer.json_key
- end
-
- def test_json_key_with_root_and_no_serializers
- expected = 'custom_root'
- serializer = collection_serializer.new(build_named_collection, root: expected)
- assert_equal expected, serializer.json_key
- end
- end
- end
-end
diff --git a/test/fixtures/active_record.rb b/test/fixtures/active_record.rb
deleted file mode 100644
index 9dc3830d..00000000
--- a/test/fixtures/active_record.rb
+++ /dev/null
@@ -1,113 +0,0 @@
-require 'active_record'
-
-ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
-ActiveRecord::Schema.define do
- self.verbose = false
- create_table :posts, force: true do |t|
- t.string :title
- t.text :body
- t.references :author
- t.timestamps null: false
- end
- create_table :authors, force: true do |t|
- t.string :name
- t.timestamps null: false
- end
- create_table :comments, force: true do |t|
- t.text :contents
- t.references :author
- t.references :post
- t.timestamp null: false
- end
- create_table :employees, force: true do |t|
- t.string :name
- t.string :email
- t.timestamp null: false
- end
- create_table :object_tags, force: true do |t|
- t.string :poly_tag_id
- t.string :taggable_type
- t.string :taggable_id
- t.timestamp null: false
- end
- create_table :poly_tags, force: true do |t|
- t.string :phrase
- t.timestamp null: false
- end
- create_table :pictures, force: true do |t|
- t.string :title
- t.string :imageable_type
- t.string :imageable_id
- t.timestamp null: false
- end
-end
-
-module ARModels
- class Post < ActiveRecord::Base
- has_many :comments
- belongs_to :author
- end
- class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body
-
- has_many :comments
- belongs_to :author
- end
-
- class Comment < ActiveRecord::Base
- belongs_to :post
- belongs_to :author
- end
- class CommentSerializer < ActiveModel::Serializer
- attributes :id, :contents
-
- belongs_to :author
- end
-
- class Author < ActiveRecord::Base
- has_many :posts
- end
- class AuthorSerializer < ActiveModel::Serializer
- attributes :id, :name
-
- has_many :posts
- end
-end
-
-class Employee < ActiveRecord::Base
- has_many :pictures, as: :imageable
- has_many :object_tags, as: :taggable
-end
-
-class PolymorphicSimpleSerializer < ActiveModel::Serializer
- attributes :id
-end
-
-class ObjectTag < ActiveRecord::Base
- belongs_to :poly_tag
- belongs_to :taggable, polymorphic: true
-end
-class PolymorphicObjectTagSerializer < ActiveModel::Serializer
- attributes :id
- has_many :taggable, serializer: PolymorphicSimpleSerializer, polymorphic: true
-end
-
-class PolyTag < ActiveRecord::Base
- has_many :object_tags
-end
-class PolymorphicTagSerializer < ActiveModel::Serializer
- attributes :id, :phrase
- has_many :object_tags, serializer: PolymorphicObjectTagSerializer
-end
-
-class Picture < ActiveRecord::Base
- belongs_to :imageable, polymorphic: true
- has_many :object_tags, as: :taggable
-end
-class PolymorphicHasManySerializer < ActiveModel::Serializer
- attributes :id, :name
-end
-class PolymorphicBelongsToSerializer < ActiveModel::Serializer
- attributes :id, :title
- has_one :imageable, serializer: PolymorphicHasManySerializer, polymorphic: true
-end
diff --git a/test/fixtures/poro.rb b/test/fixtures/poro.rb
deleted file mode 100644
index 6245ad23..00000000
--- a/test/fixtures/poro.rb
+++ /dev/null
@@ -1,225 +0,0 @@
-class Model < ActiveModelSerializers::Model
- rand(2).zero? && derive_attributes_from_names_and_fix_accessors
-
- attr_writer :id
-
- # At this time, just for organization of intent
- class_attribute :association_names
- self.association_names = []
-
- def self.associations(*names)
- self.association_names |= names.map(&:to_sym)
- # Silence redefinition of methods warnings
- ActiveModelSerializers.silence_warnings do
- attr_accessor(*names)
- end
- end
-
- def associations
- association_names.each_with_object({}) do |association_name, result|
- result[association_name] = public_send(association_name).freeze
- end.with_indifferent_access.freeze
- end
-
- def attributes
- super.except(*association_names)
- end
-end
-
-# see
-# https://github.com/rails/rails/blob/4-2-stable/activemodel/lib/active_model/errors.rb
-# The below allows you to do:
-#
-# model = ModelWithErrors.new
-# model.validate! # => ["cannot be nil"]
-# model.errors.full_messages # => ["name cannot be nil"]
-class ModelWithErrors < Model
- attributes :name
-end
-
-class Profile < Model
- attributes :name, :description
- associations :comments
-end
-class ProfileSerializer < ActiveModel::Serializer
- attributes :name, :description
-end
-class ProfilePreviewSerializer < ActiveModel::Serializer
- attributes :name
-end
-
-class Author < Model
- attributes :name
- associations :posts, :bio, :roles, :comments
-end
-class AuthorSerializer < ActiveModel::Serializer
- cache key: 'writer', skip_digest: true
- attribute :id
- attribute :name
-
- has_many :posts
- has_many :roles
- has_one :bio
-end
-class AuthorPreviewSerializer < ActiveModel::Serializer
- attributes :id
- has_many :posts
-end
-
-class Comment < Model
- attributes :body, :date
- associations :post, :author, :likes
-end
-class CommentSerializer < ActiveModel::Serializer
- cache expires_in: 1.day, skip_digest: true
- attributes :id, :body
- belongs_to :post
- belongs_to :author
-end
-class CommentPreviewSerializer < ActiveModel::Serializer
- attributes :id
-
- belongs_to :post
-end
-
-class Post < Model
- attributes :title, :body
- associations :author, :comments, :blog, :tags, :related
-end
-class PostSerializer < ActiveModel::Serializer
- cache key: 'post', expires_in: 0.1, skip_digest: true
- attributes :id, :title, :body
-
- has_many :comments
- belongs_to :blog
- belongs_to :author
-
- def blog
- Blog.new(id: 999, name: 'Custom blog')
- end
-end
-class SpammyPostSerializer < ActiveModel::Serializer
- attributes :id
- has_many :related
-end
-class PostPreviewSerializer < ActiveModel::Serializer
- attributes :title, :body, :id
-
- has_many :comments, serializer: ::CommentPreviewSerializer
- belongs_to :author, serializer: ::AuthorPreviewSerializer
-end
-class PostWithCustomKeysSerializer < ActiveModel::Serializer
- attributes :id
- has_many :comments, key: :reviews
- belongs_to :author, key: :writer
- has_one :blog, key: :site
-end
-
-class Bio < Model
- attributes :content, :rating
- associations :author
-end
-class BioSerializer < ActiveModel::Serializer
- cache except: [:content], skip_digest: true
- attributes :id, :content, :rating
-
- belongs_to :author
-end
-
-class Blog < Model
- attributes :name, :type, :special_attribute
- associations :writer, :articles
-end
-class BlogSerializer < ActiveModel::Serializer
- cache key: 'blog'
- attributes :id, :name
-
- belongs_to :writer
- has_many :articles
-end
-class AlternateBlogSerializer < ActiveModel::Serializer
- attribute :id
- attribute :name, key: :title
-end
-class CustomBlogSerializer < ActiveModel::Serializer
- attribute :id
- attribute :special_attribute
- has_many :articles
-end
-
-class Role < Model
- attributes :name, :description, :special_attribute
- associations :author
-end
-class RoleSerializer < ActiveModel::Serializer
- cache only: [:name, :slug], skip_digest: true
- attributes :id, :name, :description
- attribute :friendly_id, key: :slug
- belongs_to :author
-
- def friendly_id
- "#{object.name}-#{object.id}"
- end
-end
-
-class Location < Model
- attributes :lat, :lng
- associations :place
-end
-class LocationSerializer < ActiveModel::Serializer
- cache only: [:address], skip_digest: true
- attributes :id, :lat, :lng
-
- belongs_to :place, key: :address
-
- def place
- 'Nowhere'
- end
-end
-
-class Place < Model
- attributes :name
- associations :locations
-end
-class PlaceSerializer < ActiveModel::Serializer
- attributes :id, :name
- has_many :locations
-end
-
-class Like < Model
- attributes :time
- associations :likeable
-end
-class LikeSerializer < ActiveModel::Serializer
- attributes :id, :time
- belongs_to :likeable
-end
-
-module Spam
- class UnrelatedLink < Model
- end
- class UnrelatedLinkSerializer < ActiveModel::Serializer
- cache only: [:id]
- attributes :id
- end
-end
-
-class VirtualValue < Model; end
-class VirtualValueSerializer < ActiveModel::Serializer
- attributes :id
- has_many :reviews, virtual_value: [{ type: 'reviews', id: '1' },
- { type: 'reviews', id: '2' }]
- has_one :maker, virtual_value: { type: 'makers', id: '1' }
-
- def reviews
- end
-
- def maker
- end
-end
-
-class PaginatedSerializer < ActiveModel::Serializer::CollectionSerializer
- def json_key
- 'paginated'
- end
-end
diff --git a/test/generators/scaffold_controller_generator_test.rb b/test/generators/scaffold_controller_generator_test.rb
deleted file mode 100644
index 183bb4f6..00000000
--- a/test/generators/scaffold_controller_generator_test.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-require 'test_helper'
-require 'generators/rails/resource_override'
-
-class ResourceGeneratorTest < Rails::Generators::TestCase
- destination File.expand_path('../../../tmp/generators', __FILE__)
- setup :prepare_destination, :copy_routes
-
- tests Rails::Generators::ResourceGenerator
- arguments %w(account)
-
- def test_serializer_file_is_generated
- run_generator
-
- assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ActiveModel::Serializer/
- end
-
- private
-
- def copy_routes
- config_dir = File.join(destination_root, 'config')
- FileUtils.mkdir_p(config_dir)
- File.write(File.join(config_dir, 'routes.rb'), 'Rails.application.routes.draw {}')
- end
-end
diff --git a/test/generators/serializer_generator_test.rb b/test/generators/serializer_generator_test.rb
deleted file mode 100644
index eef4a41e..00000000
--- a/test/generators/serializer_generator_test.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-require 'test_helper'
-require 'generators/rails/resource_override'
-require 'generators/rails/serializer_generator'
-
-class SerializerGeneratorTest < Rails::Generators::TestCase
- destination File.expand_path('../../../tmp/generators', __FILE__)
- setup :prepare_destination
-
- tests Rails::Generators::SerializerGenerator
- arguments %w(account name:string description:text business:references)
-
- def test_generates_a_serializer
- run_generator
- assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ActiveModel::Serializer/
- end
-
- def test_generates_a_namespaced_serializer
- run_generator ['admin/account']
- assert_file 'app/serializers/admin/account_serializer.rb', /class Admin::AccountSerializer < ActiveModel::Serializer/
- end
-
- def test_uses_application_serializer_if_one_exists
- stub_safe_constantize(expected: 'ApplicationSerializer') do
- run_generator
- assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ApplicationSerializer/
- end
- end
-
- def test_uses_given_parent
- Object.const_set(:ApplicationSerializer, Class.new)
- run_generator ['Account', '--parent=MySerializer']
- assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < MySerializer/
- ensure
- Object.send :remove_const, :ApplicationSerializer
- end
-
- def test_generates_attributes_and_associations
- run_generator
- assert_file 'app/serializers/account_serializer.rb' do |serializer|
- assert_match(/^ attributes :id, :name, :description$/, serializer)
- assert_match(/^ has_one :business$/, serializer)
- assert_match(/^end\n*\z/, serializer)
- end
- end
-
- def test_with_no_attributes_does_not_add_extra_space
- run_generator ['account']
- assert_file 'app/serializers/account_serializer.rb' do |content|
- if RUBY_PLATFORM =~ /mingw/
- assert_no_match(/\r\n\r\nend/, content)
- else
- assert_no_match(/\n\nend/, content)
- end
- end
- end
-
- private
-
- def stub_safe_constantize(expected:)
- String.class_eval do
- alias_method :old, :safe_constantize
- end
- String.send(:define_method, :safe_constantize) do
- Class if self == expected
- end
-
- yield
- ensure
- String.class_eval do
- undef_method :safe_constantize
- alias_method :safe_constantize, :old
- undef_method :old
- end
- end
-end
diff --git a/test/grape_test.rb b/test/grape_test.rb
deleted file mode 100644
index 4851e57a..00000000
--- a/test/grape_test.rb
+++ /dev/null
@@ -1,196 +0,0 @@
-require 'test_helper'
-TestHelper.silence_warnings do
- require 'grape'
-end
-require 'grape/active_model_serializers'
-require 'kaminari'
-require 'kaminari/hooks'
-::Kaminari::Hooks.init
-
-module ActiveModelSerializers
- class GrapeTest < ActiveSupport::TestCase
- include Rack::Test::Methods
- module Models
- def self.model1
- ARModels::Post.new(id: 1, title: 'Dummy Title', body: 'Lorem Ipsum')
- end
-
- def self.model2
- ARModels::Post.new(id: 2, title: 'Second Dummy Title', body: 'Second Lorem Ipsum')
- end
-
- def self.all
- @all ||=
- begin
- model1.save!
- model2.save!
- ARModels::Post.all
- end
- end
-
- def self.reset_all
- ARModels::Post.delete_all
- @all = nil
- end
-
- def self.collection_per
- 2
- end
-
- def self.collection
- @collection ||=
- begin
- Kaminari.paginate_array(
- [
- Profile.new(id: 1, name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
- Profile.new(id: 2, name: 'Name 2', description: 'Description 2', comments: 'Comments 2'),
- Profile.new(id: 3, name: 'Name 3', description: 'Description 3', comments: 'Comments 3'),
- Profile.new(id: 4, name: 'Name 4', description: 'Description 4', comments: 'Comments 4'),
- Profile.new(id: 5, name: 'Name 5', description: 'Description 5', comments: 'Comments 5')
- ]
- ).page(1).per(collection_per)
- end
- end
- end
-
- class GrapeTest < Grape::API
- format :json
- TestHelper.silence_warnings do
- include Grape::ActiveModelSerializers
- end
-
- def self.resources(*)
- TestHelper.silence_warnings do
- super
- end
- end
-
- resources :grape do
- get '/render' do
- render Models.model1
- end
-
- get '/render_with_json_api' do
- post = Models.model1
- render post, meta: { page: 1, total_pages: 2 }, adapter: :json_api
- end
-
- get '/render_array_with_json_api' do
- posts = Models.all
- render posts, adapter: :json_api
- end
-
- get '/render_collection_with_json_api' do
- posts = Models.collection
- render posts, adapter: :json_api
- end
-
- get '/render_with_implicit_formatter' do
- Models.model1
- end
-
- get '/render_array_with_implicit_formatter' do
- Models.all
- end
-
- get '/render_collection_with_implicit_formatter' do
- Models.collection
- end
- end
- end
-
- def app
- Grape::Middleware::Globals.new(GrapeTest.new)
- end
-
- extend Minitest::Assertions
- def self.run_one_method(*)
- _, stderr = capture_io do
- super
- end
- fail Minitest::Assertion, stderr if stderr !~ /grape/
- end
-
- def test_formatter_returns_json
- get '/grape/render'
-
- post = Models.model1
- serializable_resource = serializable(post)
-
- assert last_response.ok?
- assert_equal serializable_resource.to_json, last_response.body
- end
-
- def test_render_helper_passes_through_options_correctly
- get '/grape/render_with_json_api'
-
- post = Models.model1
- serializable_resource = serializable(post, serializer: ARModels::PostSerializer, adapter: :json_api, meta: { page: 1, total_pages: 2 })
-
- assert last_response.ok?
- assert_equal serializable_resource.to_json, last_response.body
- end
-
- def test_formatter_handles_arrays
- get '/grape/render_array_with_json_api'
-
- posts = Models.all
- serializable_resource = serializable(posts, adapter: :json_api)
-
- assert last_response.ok?
- assert_equal serializable_resource.to_json, last_response.body
- ensure
- Models.reset_all
- end
-
- def test_formatter_handles_collections
- get '/grape/render_collection_with_json_api'
- assert last_response.ok?
-
- representation = JSON.parse(last_response.body)
- assert representation.include?('data')
- assert representation['data'].count == Models.collection_per
- assert representation.include?('links')
- assert representation['links'].count > 0
- end
-
- def test_implicit_formatter
- post = Models.model1
- serializable_resource = serializable(post, adapter: :json_api)
-
- with_adapter :json_api do
- get '/grape/render_with_implicit_formatter'
- end
-
- assert last_response.ok?
- assert_equal serializable_resource.to_json, last_response.body
- end
-
- def test_implicit_formatter_handles_arrays
- posts = Models.all
- serializable_resource = serializable(posts, adapter: :json_api)
-
- with_adapter :json_api do
- get '/grape/render_array_with_implicit_formatter'
- end
-
- assert last_response.ok?
- assert_equal serializable_resource.to_json, last_response.body
- ensure
- Models.reset_all
- end
-
- def test_implicit_formatter_handles_collections
- with_adapter :json_api do
- get '/grape/render_collection_with_implicit_formatter'
- end
-
- representation = JSON.parse(last_response.body)
- assert last_response.ok?
- assert representation.include?('data')
- assert representation['data'].count == Models.collection_per
- assert representation.include?('links')
- assert representation['links'].count > 0
- end
- end
-end
diff --git a/test/lint_test.rb b/test/lint_test.rb
deleted file mode 100644
index d404ccec..00000000
--- a/test/lint_test.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class LintTest < ActiveSupport::TestCase
- include ActiveModel::Serializer::Lint::Tests
-
- class CompliantResource
- def serializable_hash(options = nil)
- end
-
- def read_attribute_for_serialization(name)
- end
-
- def as_json(options = nil)
- end
-
- def to_json(options = nil)
- end
-
- def cache_key
- end
-
- def id
- end
-
- def updated_at
- end
-
- def errors
- end
-
- def self.human_attribute_name(_, _ = {})
- end
-
- def self.lookup_ancestors
- end
-
- def self.model_name
- @_model_name ||= ActiveModel::Name.new(self)
- end
- end
-
- def setup
- @resource = CompliantResource.new
- end
- end
- end
-end
diff --git a/test/logger_test.rb b/test/logger_test.rb
deleted file mode 100644
index a15227bb..00000000
--- a/test/logger_test.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- class LoggerTest < ActiveSupport::TestCase
- def test_logger_is_set_to_action_controller_logger_when_initializer_runs
- assert_equal $action_controller_logger, ActionController::Base.logger # rubocop:disable Style/GlobalVars
- end
-
- def test_logger_can_be_set
- original_logger = ActiveModelSerializers.logger
- logger = Logger.new(STDOUT)
-
- ActiveModelSerializers.logger = logger
-
- assert_equal ActiveModelSerializers.logger, logger
- ensure
- ActiveModelSerializers.logger = original_logger
- end
- end
-end
diff --git a/test/poro_test.rb b/test/poro_test.rb
deleted file mode 100644
index e5fba858..00000000
--- a/test/poro_test.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'test_helper'
-
-class PoroTest < ActiveSupport::TestCase
- include ActiveModel::Serializer::Lint::Tests
-
- def setup
- @resource = Model.new
- end
-end
diff --git a/test/serializable_resource_test.rb b/test/serializable_resource_test.rb
deleted file mode 100644
index ab12bc27..00000000
--- a/test/serializable_resource_test.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-require 'test_helper'
-
-module ActiveModelSerializers
- class SerializableResourceTest < ActiveSupport::TestCase
- def setup
- @resource = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- @serializer = ProfileSerializer.new(@resource)
- @adapter = ActiveModelSerializers::Adapter.create(@serializer)
- @serializable_resource = SerializableResource.new(@resource)
- end
-
- def test_deprecation
- assert_output(nil, /deprecated/) do
- deprecated_serializable_resource = ActiveModel::SerializableResource.new(@resource)
- assert_equal(@serializable_resource.as_json, deprecated_serializable_resource.as_json)
- end
- end
-
- def test_serializable_resource_delegates_serializable_hash_to_the_adapter
- options = nil
- assert_equal @adapter.serializable_hash(options), @serializable_resource.serializable_hash(options)
- end
-
- def test_serializable_resource_delegates_to_json_to_the_adapter
- options = nil
- assert_equal @adapter.to_json(options), @serializable_resource.to_json(options)
- end
-
- def test_serializable_resource_delegates_as_json_to_the_adapter
- options = nil
- assert_equal @adapter.as_json(options), @serializable_resource.as_json(options)
- end
-
- def test_use_adapter_with_adapter_option
- assert SerializableResource.new(@resource, adapter: 'json').use_adapter?
- end
-
- def test_use_adapter_with_adapter_option_as_false
- refute SerializableResource.new(@resource, adapter: false).use_adapter?
- end
-
- class SerializableResourceErrorsTest < Minitest::Test
- def test_serializable_resource_with_errors
- options = nil
- resource = ModelWithErrors.new
- resource.errors.add(:name, 'must be awesome')
- serializable_resource = ActiveModelSerializers::SerializableResource.new(
- resource, serializer: ActiveModel::Serializer::ErrorSerializer,
- adapter: :json_api
- )
- expected_response_document = {
- errors: [
- { source: { pointer: '/data/attributes/name' }, detail: 'must be awesome' }
- ]
- }
- assert_equal serializable_resource.as_json(options), expected_response_document
- end
-
- def test_serializable_resource_with_collection_containing_errors
- options = nil
- resources = []
- resources << resource = ModelWithErrors.new
- resource.errors.add(:title, 'must be amazing')
- resources << ModelWithErrors.new
- serializable_resource = SerializableResource.new(
- resources, serializer: ActiveModel::Serializer::ErrorsSerializer,
- each_serializer: ActiveModel::Serializer::ErrorSerializer,
- adapter: :json_api
- )
- expected_response_document = {
- errors: [
- { source: { pointer: '/data/attributes/title' }, detail: 'must be amazing' }
- ]
- }
- assert_equal serializable_resource.as_json(options), expected_response_document
- end
- end
- end
-end
diff --git a/test/serializers/association_macros_test.rb b/test/serializers/association_macros_test.rb
deleted file mode 100644
index 3d5f05c5..00000000
--- a/test/serializers/association_macros_test.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class AssociationMacrosTest < ActiveSupport::TestCase
- class AuthorSummarySerializer < ActiveModel::Serializer; end
-
- class AssociationsTestSerializer < Serializer
- belongs_to :author, serializer: AuthorSummarySerializer
- has_many :comments
- has_one :category
- end
-
- def before_setup
- @reflections = AssociationsTestSerializer._reflections.values
- end
-
- def test_has_one_defines_reflection
- has_one_reflection = HasOneReflection.new(:category, {})
-
- assert_includes(@reflections, has_one_reflection)
- end
-
- def test_has_many_defines_reflection
- has_many_reflection = HasManyReflection.new(:comments, {})
-
- assert_includes(@reflections, has_many_reflection)
- end
-
- def test_belongs_to_defines_reflection
- belongs_to_reflection = BelongsToReflection.new(:author, serializer: AuthorSummarySerializer)
-
- assert_includes(@reflections, belongs_to_reflection)
- end
- end
- end
-end
diff --git a/test/serializers/associations_test.rb b/test/serializers/associations_test.rb
deleted file mode 100644
index c1b164b8..00000000
--- a/test/serializers/associations_test.rb
+++ /dev/null
@@ -1,424 +0,0 @@
-require 'test_helper'
-module ActiveModel
- class Serializer
- class AssociationsTest < ActiveSupport::TestCase
- class ModelWithoutSerializer < ::Model
- attributes :id, :name
- end
-
- def setup
- @author = Author.new(name: 'Steve K.')
- @author.bio = nil
- @author.roles = []
- @blog = Blog.new(name: 'AMS Blog')
- @post = Post.new(title: 'New Post', body: 'Body')
- @tag = ModelWithoutSerializer.new(id: 'tagid', name: '#hashtagged')
- @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
- @post.comments = [@comment]
- @post.tags = [@tag]
- @post.blog = @blog
- @comment.post = @post
- @comment.author = nil
- @post.author = @author
- @author.posts = [@post]
-
- @post_serializer = PostSerializer.new(@post, custom_options: true)
- @author_serializer = AuthorSerializer.new(@author)
- @comment_serializer = CommentSerializer.new(@comment)
- end
-
- def test_has_many_and_has_one
- @author_serializer.associations.each do |association|
- key = association.key
- serializer = association.lazy_association.serializer
-
- case key
- when :posts
- assert_equal true, association.include_data?
- assert_kind_of(ActiveModelSerializers.config.collection_serializer, serializer)
- when :bio
- assert_equal true, association.include_data?
- assert_nil serializer
- when :roles
- assert_equal true, association.include_data?
- assert_kind_of(ActiveModelSerializers.config.collection_serializer, serializer)
- else
- flunk "Unknown association: #{key}"
- end
- end
- end
-
- def test_has_many_with_no_serializer
- post_serializer_class = Class.new(ActiveModel::Serializer) do
- attributes :id
- has_many :tags
- end
- post_serializer_class.new(@post).associations.each do |association|
- key = association.key
- serializer = association.lazy_association.serializer
-
- assert_equal :tags, key
- assert_nil serializer
- assert_equal [{ id: 'tagid', name: '#hashtagged' }].to_json, association.virtual_value.to_json
- end
- end
-
- def test_serializer_options_are_passed_into_associations_serializers
- association = @post_serializer
- .associations
- .detect { |assoc| assoc.key == :comments }
-
- comment_serializer = association.lazy_association.serializer.first
- class << comment_serializer
- def custom_options
- instance_options
- end
- end
- assert comment_serializer.custom_options.fetch(:custom_options)
- end
-
- def test_belongs_to
- @comment_serializer.associations.each do |association|
- key = association.key
- serializer = association.lazy_association.serializer
-
- case key
- when :post
- assert_kind_of(PostSerializer, serializer)
- when :author
- assert_nil serializer
- else
- flunk "Unknown association: #{key}"
- end
-
- assert_equal true, association.include_data?
- end
- end
-
- def test_belongs_to_with_custom_method
- assert(
- @post_serializer.associations.any? do |association|
- association.key == :blog
- end
- )
- end
-
- def test_associations_inheritance
- inherited_klass = Class.new(PostSerializer)
-
- assert_equal(PostSerializer._reflections, inherited_klass._reflections)
- end
-
- def test_associations_inheritance_with_new_association
- inherited_klass = Class.new(PostSerializer) do
- has_many :top_comments, serializer: CommentSerializer
- end
-
- assert(
- PostSerializer._reflections.values.all? do |reflection|
- inherited_klass._reflections.values.include?(reflection)
- end
- )
-
- assert(
- inherited_klass._reflections.values.any? do |reflection|
- reflection.name == :top_comments
- end
- )
- end
-
- def test_associations_custom_keys
- serializer = PostWithCustomKeysSerializer.new(@post)
-
- expected_association_keys = serializer.associations.map(&:key)
-
- assert expected_association_keys.include? :reviews
- assert expected_association_keys.include? :writer
- assert expected_association_keys.include? :site
- end
-
- class BelongsToBlogModel < ::Model
- attributes :id, :title
- associations :blog
- end
- class BelongsToBlogModelSerializer < ActiveModel::Serializer
- type :posts
- belongs_to :blog
- end
-
- def test_belongs_to_doesnt_load_record
- attributes = { id: 1, title: 'Belongs to Blog', blog: Blog.new(id: 5) }
- post = BelongsToBlogModel.new(attributes)
- class << post
- def blog
- fail 'should use blog_id'
- end
-
- def blog_id
- 5
- end
- end
-
- actual = serializable(post, adapter: :json_api, serializer: BelongsToBlogModelSerializer).as_json
- expected = { data: { id: '1', type: 'posts', relationships: { blog: { data: { id: '5', type: 'blogs' } } } } }
-
- assert_equal expected, actual
- end
-
- class InlineAssociationTestPostSerializer < ActiveModel::Serializer
- has_many :comments
- has_many :comments, key: :last_comments do
- object.comments.last(1)
- end
- end
-
- def test_virtual_attribute_block
- comment1 = ::ARModels::Comment.create!(contents: 'first comment')
- comment2 = ::ARModels::Comment.create!(contents: 'last comment')
- post = ::ARModels::Post.create!(
- title: 'inline association test',
- body: 'etc',
- comments: [comment1, comment2]
- )
- actual = serializable(post, adapter: :attributes, serializer: InlineAssociationTestPostSerializer).as_json
- expected = {
- comments: [
- { id: 1, contents: 'first comment' },
- { id: 2, contents: 'last comment' }
- ],
- last_comments: [
- { id: 2, contents: 'last comment' }
- ]
- }
-
- assert_equal expected, actual
- ensure
- ::ARModels::Post.delete_all
- ::ARModels::Comment.delete_all
- end
-
- class NamespacedResourcesTest < ActiveSupport::TestCase
- class ResourceNamespace
- class Post < ::Model
- associations :comments, :author, :description
- end
- class Comment < ::Model; end
- class Author < ::Model; end
- class Description < ::Model; end
- class PostSerializer < ActiveModel::Serializer
- has_many :comments
- belongs_to :author
- has_one :description
- end
- class CommentSerializer < ActiveModel::Serializer; end
- class AuthorSerializer < ActiveModel::Serializer; end
- class DescriptionSerializer < ActiveModel::Serializer; end
- end
-
- def setup
- @comment = ResourceNamespace::Comment.new
- @author = ResourceNamespace::Author.new
- @description = ResourceNamespace::Description.new
- @post = ResourceNamespace::Post.new(comments: [@comment],
- author: @author,
- description: @description)
- @post_serializer = ResourceNamespace::PostSerializer.new(@post)
- end
-
- def test_associations_namespaced_resources
- @post_serializer.associations.each do |association|
- case association.key
- when :comments
- assert_instance_of(ResourceNamespace::CommentSerializer, association.lazy_association.serializer.first)
- when :author
- assert_instance_of(ResourceNamespace::AuthorSerializer, association.lazy_association.serializer)
- when :description
- assert_instance_of(ResourceNamespace::DescriptionSerializer, association.lazy_association.serializer)
- else
- flunk "Unknown association: #{key}"
- end
- end
- end
- end
-
- class NestedSerializersTest < ActiveSupport::TestCase
- class Post < ::Model
- associations :comments, :author, :description
- end
- class Comment < ::Model; end
- class Author < ::Model; end
- class Description < ::Model; end
- class PostSerializer < ActiveModel::Serializer
- has_many :comments
- class CommentSerializer < ActiveModel::Serializer; end
- belongs_to :author
- class AuthorSerializer < ActiveModel::Serializer; end
- has_one :description
- class DescriptionSerializer < ActiveModel::Serializer; end
- end
-
- def setup
- @comment = Comment.new
- @author = Author.new
- @description = Description.new
- @post = Post.new(comments: [@comment],
- author: @author,
- description: @description)
- @post_serializer = PostSerializer.new(@post)
- end
-
- def test_associations_namespaced_resources
- @post_serializer.associations.each do |association|
- case association.key
- when :comments
- assert_instance_of(PostSerializer::CommentSerializer, association.lazy_association.serializer.first)
- when :author
- assert_instance_of(PostSerializer::AuthorSerializer, association.lazy_association.serializer)
- when :description
- assert_instance_of(PostSerializer::DescriptionSerializer, association.lazy_association.serializer)
- else
- flunk "Unknown association: #{key}"
- end
- end
- end
-
- # rubocop:disable Metrics/AbcSize
- def test_conditional_associations
- model = Class.new(::Model) do
- attributes :true, :false
- associations :something
- end.new(true: true, false: false)
-
- scenarios = [
- { options: { if: :true }, included: true },
- { options: { if: :false }, included: false },
- { options: { unless: :false }, included: true },
- { options: { unless: :true }, included: false },
- { options: { if: 'object.true' }, included: true },
- { options: { if: 'object.false' }, included: false },
- { options: { unless: 'object.false' }, included: true },
- { options: { unless: 'object.true' }, included: false },
- { options: { if: -> { object.true } }, included: true },
- { options: { if: -> { object.false } }, included: false },
- { options: { unless: -> { object.false } }, included: true },
- { options: { unless: -> { object.true } }, included: false },
- { options: { if: -> (s) { s.object.true } }, included: true },
- { options: { if: -> (s) { s.object.false } }, included: false },
- { options: { unless: -> (s) { s.object.false } }, included: true },
- { options: { unless: -> (s) { s.object.true } }, included: false }
- ]
-
- scenarios.each do |s|
- serializer = Class.new(ActiveModel::Serializer) do
- belongs_to :something, s[:options]
-
- def true
- true
- end
-
- def false
- false
- end
- end
-
- hash = serializable(model, serializer: serializer).serializable_hash
- assert_equal(s[:included], hash.key?(:something), "Error with #{s[:options]}")
- end
- end
-
- def test_illegal_conditional_associations
- exception = assert_raises(TypeError) do
- Class.new(ActiveModel::Serializer) do
- belongs_to :x, if: nil
- end
- end
-
- assert_match(/:if should be a Symbol, String or Proc/, exception.message)
- end
- end
-
- class InheritedSerializerTest < ActiveSupport::TestCase
- class PostSerializer < ActiveModel::Serializer
- belongs_to :author
- has_many :comments
- belongs_to :blog
- end
-
- class InheritedPostSerializer < PostSerializer
- belongs_to :author, polymorphic: true
- has_many :comments, key: :reviews
- end
-
- class AuthorSerializer < ActiveModel::Serializer
- has_many :posts
- has_many :roles
- has_one :bio
- end
-
- class InheritedAuthorSerializer < AuthorSerializer
- has_many :roles, polymorphic: true
- has_one :bio, polymorphic: true
- end
-
- def setup
- @author = Author.new(name: 'Steve K.')
- @post = Post.new(title: 'New Post', body: 'Body')
- @post_serializer = PostSerializer.new(@post)
- @author_serializer = AuthorSerializer.new(@author)
- @inherited_post_serializer = InheritedPostSerializer.new(@post)
- @inherited_author_serializer = InheritedAuthorSerializer.new(@author)
- @author_associations = @author_serializer.associations.to_a.sort_by(&:name)
- @inherited_author_associations = @inherited_author_serializer.associations.to_a.sort_by(&:name)
- @post_associations = @post_serializer.associations.to_a
- @inherited_post_associations = @inherited_post_serializer.associations.to_a
- end
-
- test 'an author serializer must have [posts,roles,bio] associations' do
- expected = [:posts, :roles, :bio].sort
- result = @author_serializer.associations.map(&:name).sort
- assert_equal(result, expected)
- end
-
- test 'a post serializer must have [author,comments,blog] associations' do
- expected = [:author, :comments, :blog].sort
- result = @post_serializer.associations.map(&:name).sort
- assert_equal(result, expected)
- end
-
- test 'a serializer inheriting from another serializer can redefine has_many and has_one associations' do
- expected = [:roles, :bio].sort
- result = (@inherited_author_associations.map(&:reflection) - @author_associations.map(&:reflection)).map(&:name)
- assert_equal(result, expected)
- assert_equal [true, false, true], @inherited_author_associations.map(&:polymorphic?)
- assert_equal [false, false, false], @author_associations.map(&:polymorphic?)
- end
-
- test 'a serializer inheriting from another serializer can redefine belongs_to associations' do
- assert_equal [:author, :comments, :blog], @post_associations.map(&:name)
- assert_equal [:author, :comments, :blog, :comments], @inherited_post_associations.map(&:name)
-
- refute @post_associations.detect { |assoc| assoc.name == :author }.polymorphic?
- assert @inherited_post_associations.detect { |assoc| assoc.name == :author }.polymorphic?
-
- refute @post_associations.detect { |assoc| assoc.name == :comments }.key?
- original_comment_assoc, new_comments_assoc = @inherited_post_associations.select { |assoc| assoc.name == :comments }
- refute original_comment_assoc.key?
- assert_equal :reviews, new_comments_assoc.key
-
- original_blog = @post_associations.detect { |assoc| assoc.name == :blog }
- inherited_blog = @inherited_post_associations.detect { |assoc| assoc.name == :blog }
- original_parent_serializer = original_blog.lazy_association.association_options.delete(:parent_serializer)
- inherited_parent_serializer = inherited_blog.lazy_association.association_options.delete(:parent_serializer)
- assert_equal PostSerializer, original_parent_serializer.class
- assert_equal InheritedPostSerializer, inherited_parent_serializer.class
- end
-
- test 'a serializer inheriting from another serializer can have an additional association with the same name but with different key' do
- expected = [:author, :comments, :blog, :reviews].sort
- result = @inherited_post_serializer.associations.map(&:key).sort
- assert_equal(result, expected)
- end
- end
- end
- end
-end
diff --git a/test/serializers/attribute_test.rb b/test/serializers/attribute_test.rb
deleted file mode 100644
index 608898c3..00000000
--- a/test/serializers/attribute_test.rb
+++ /dev/null
@@ -1,153 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class AttributeTest < ActiveSupport::TestCase
- def setup
- @blog = Blog.new(id: 1, name: 'AMS Hints', type: 'stuff')
- @blog_serializer = AlternateBlogSerializer.new(@blog)
- end
-
- def test_attributes_definition
- assert_equal([:id, :title],
- @blog_serializer.class._attributes)
- end
-
- def test_json_serializable_hash
- adapter = ActiveModelSerializers::Adapter::Json.new(@blog_serializer)
- assert_equal({ blog: { id: 1, title: 'AMS Hints' } }, adapter.serializable_hash)
- end
-
- def test_attribute_inheritance_with_key
- inherited_klass = Class.new(AlternateBlogSerializer)
- blog_serializer = inherited_klass.new(@blog)
- adapter = ActiveModelSerializers::Adapter::Attributes.new(blog_serializer)
- assert_equal({ id: 1, title: 'AMS Hints' }, adapter.serializable_hash)
- end
-
- def test_multiple_calls_with_the_same_attribute
- serializer_class = Class.new(ActiveModel::Serializer) do
- attribute :title
- attribute :title
- end
-
- assert_equal([:title], serializer_class._attributes)
- end
-
- def test_id_attribute_override
- serializer = Class.new(ActiveModel::Serializer) do
- attribute :name, key: :id
- end
-
- adapter = ActiveModelSerializers::Adapter::Json.new(serializer.new(@blog))
- assert_equal({ blog: { id: 'AMS Hints' } }, adapter.serializable_hash)
- end
-
- def test_object_attribute_override
- serializer = Class.new(ActiveModel::Serializer) do
- attribute :name, key: :object
- end
-
- adapter = ActiveModelSerializers::Adapter::Json.new(serializer.new(@blog))
- assert_equal({ blog: { object: 'AMS Hints' } }, adapter.serializable_hash)
- end
-
- def test_type_attribute
- attribute_serializer = Class.new(ActiveModel::Serializer) do
- attribute :id, key: :type
- end
- attributes_serializer = Class.new(ActiveModel::Serializer) do
- attributes :type
- end
-
- adapter = ActiveModelSerializers::Adapter::Json.new(attribute_serializer.new(@blog))
- assert_equal({ blog: { type: 1 } }, adapter.serializable_hash)
-
- adapter = ActiveModelSerializers::Adapter::Json.new(attributes_serializer.new(@blog))
- assert_equal({ blog: { type: 'stuff' } }, adapter.serializable_hash)
- end
-
- def test_id_attribute_override_before
- serializer = Class.new(ActiveModel::Serializer) do
- def id
- 'custom'
- end
-
- attribute :id
- end
-
- hash = ActiveModelSerializers::SerializableResource.new(@blog, adapter: :json, serializer: serializer).serializable_hash
-
- assert_equal('custom', hash[:blog][:id])
- end
-
- class PostWithVirtualAttribute < ::Model; attributes :first_name, :last_name end
- class PostWithVirtualAttributeSerializer < ActiveModel::Serializer
- attribute :name do
- "#{object.first_name} #{object.last_name}"
- end
- end
-
- def test_virtual_attribute_block
- post = PostWithVirtualAttribute.new(first_name: 'Lucas', last_name: 'Hosseini')
- hash = serializable(post).serializable_hash
- expected = { name: 'Lucas Hosseini' }
-
- assert_equal(expected, hash)
- end
-
- # rubocop:disable Metrics/AbcSize
- def test_conditional_associations
- model = Class.new(::Model) do
- attributes :true, :false, :attribute
- end.new(true: true, false: false)
-
- scenarios = [
- { options: { if: :true }, included: true },
- { options: { if: :false }, included: false },
- { options: { unless: :false }, included: true },
- { options: { unless: :true }, included: false },
- { options: { if: 'object.true' }, included: true },
- { options: { if: 'object.false' }, included: false },
- { options: { unless: 'object.false' }, included: true },
- { options: { unless: 'object.true' }, included: false },
- { options: { if: -> { object.true } }, included: true },
- { options: { if: -> { object.false } }, included: false },
- { options: { unless: -> { object.false } }, included: true },
- { options: { unless: -> { object.true } }, included: false },
- { options: { if: -> (s) { s.object.true } }, included: true },
- { options: { if: -> (s) { s.object.false } }, included: false },
- { options: { unless: -> (s) { s.object.false } }, included: true },
- { options: { unless: -> (s) { s.object.true } }, included: false }
- ]
-
- scenarios.each do |s|
- serializer = Class.new(ActiveModel::Serializer) do
- attribute :attribute, s[:options]
-
- def true
- true
- end
-
- def false
- false
- end
- end
-
- hash = serializable(model, serializer: serializer).serializable_hash
- assert_equal(s[:included], hash.key?(:attribute), "Error with #{s[:options]}")
- end
- end
-
- def test_illegal_conditional_attributes
- exception = assert_raises(TypeError) do
- Class.new(ActiveModel::Serializer) do
- attribute :x, if: nil
- end
- end
-
- assert_match(/:if should be a Symbol, String or Proc/, exception.message)
- end
- end
- end
-end
diff --git a/test/serializers/attributes_test.rb b/test/serializers/attributes_test.rb
deleted file mode 100644
index fb792b26..00000000
--- a/test/serializers/attributes_test.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class AttributesTest < ActiveSupport::TestCase
- def setup
- @profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
- @profile_serializer = ProfileSerializer.new(@profile)
- @comment = Comment.new(id: 1, body: 'ZOMG!!', date: '2015')
- @serializer_klass = Class.new(CommentSerializer)
- @serializer_klass_with_new_attributes = Class.new(CommentSerializer) do
- attributes :date, :likes
- end
- end
-
- def test_attributes_definition
- assert_equal([:name, :description],
- @profile_serializer.class._attributes)
- end
-
- def test_attributes_inheritance_definition
- assert_equal([:id, :body], @serializer_klass._attributes)
- end
-
- def test_attributes_inheritance
- serializer = @serializer_klass.new(@comment)
- assert_equal({ id: 1, body: 'ZOMG!!' },
- serializer.attributes)
- end
-
- def test_attribute_inheritance_with_new_attribute_definition
- assert_equal([:id, :body, :date, :likes], @serializer_klass_with_new_attributes._attributes)
- assert_equal([:id, :body], CommentSerializer._attributes)
- end
-
- def test_attribute_inheritance_with_new_attribute
- serializer = @serializer_klass_with_new_attributes.new(@comment)
- assert_equal({ id: 1, body: 'ZOMG!!', date: '2015', likes: nil },
- serializer.attributes)
- end
-
- def test_multiple_calls_with_the_same_attribute
- serializer_class = Class.new(ActiveModel::Serializer) do
- attributes :id, :title
- attributes :id, :title, :title, :body
- end
-
- assert_equal([:id, :title, :body], serializer_class._attributes)
- end
- end
- end
-end
diff --git a/test/serializers/caching_configuration_test_isolated.rb b/test/serializers/caching_configuration_test_isolated.rb
deleted file mode 100644
index b5698dd1..00000000
--- a/test/serializers/caching_configuration_test_isolated.rb
+++ /dev/null
@@ -1,170 +0,0 @@
-# Execute this test in isolation
-require 'support/isolated_unit'
-
-class CachingConfigurationTest < ActiveSupport::TestCase
- include ActiveSupport::Testing::Isolation
-
- setup do
- require 'rails'
- # AMS needs to be required before Rails.application is initialized for
- # Railtie's to fire in Rails.application.initialize!
- # (and make_basic_app initializes the app)
- require 'active_model_serializers'
- # Create serializers before Rails.application.initialize!
- # To ensure we're testing that the cache settings depend on
- # the Railtie firing, not on the ActionController being loaded.
- create_serializers
- end
-
- def create_serializers
- @cached_serializer = Class.new(ActiveModel::Serializer) do
- cache skip_digest: true
- attributes :id, :name, :title
- end
- @fragment_cached_serializer = Class.new(ActiveModel::Serializer) do
- cache only: :id
- attributes :id, :name, :title
- end
- @non_cached_serializer = Class.new(ActiveModel::Serializer) do
- attributes :id, :name, :title
- end
- end
-
- class PerformCachingTrue < CachingConfigurationTest
- setup do
- # Let's make that Rails app and initialize it!
- make_basic_app do |app|
- app.config.action_controller.perform_caching = true
- app.config.action_controller.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
- end
- controller_cache_store # Force ActiveSupport.on_load(:action_controller) to run
- end
-
- test 'it sets perform_caching to true on AMS.config and serializers' do
- assert Rails.configuration.action_controller.perform_caching
- assert ActiveModelSerializers.config.perform_caching
- assert ActiveModel::Serializer.perform_caching?
- assert @cached_serializer.perform_caching?
- assert @non_cached_serializer.perform_caching?
- assert @fragment_cached_serializer.perform_caching?
- end
-
- test 'it sets the AMS.config.cache_store to the controller cache_store' do
- assert_equal controller_cache_store, ActiveSupport::Cache::MemoryStore
- assert_equal controller_cache_store, ActiveModelSerializers.config.cache_store.class
- end
-
- test 'it sets the cached serializer cache_store to the ActionController::Base.cache_store' do
- assert_equal ActiveSupport::Cache::NullStore, @cached_serializer._cache.class
- assert_equal controller_cache_store, @cached_serializer.cache_store.class
- assert_equal ActiveSupport::Cache::MemoryStore, @cached_serializer._cache.class
- end
-
- test 'the cached serializer has cache_enabled?' do
- assert @cached_serializer.cache_enabled?
- end
-
- test 'the cached serializer does not have fragment_cache_enabled?' do
- refute @cached_serializer.fragment_cache_enabled?
- end
-
- test 'the non-cached serializer cache_store is nil' do
- assert_nil @non_cached_serializer._cache
- assert_nil @non_cached_serializer.cache_store
- assert_nil @non_cached_serializer._cache
- end
-
- test 'the non-cached serializer does not have cache_enabled?' do
- refute @non_cached_serializer.cache_enabled?
- end
-
- test 'the non-cached serializer does not have fragment_cache_enabled?' do
- refute @non_cached_serializer.fragment_cache_enabled?
- end
-
- test 'it sets the fragment cached serializer cache_store to the ActionController::Base.cache_store' do
- assert_equal ActiveSupport::Cache::NullStore, @fragment_cached_serializer._cache.class
- assert_equal controller_cache_store, @fragment_cached_serializer.cache_store.class
- assert_equal ActiveSupport::Cache::MemoryStore, @fragment_cached_serializer._cache.class
- end
-
- test 'the fragment cached serializer does not have cache_enabled?' do
- refute @fragment_cached_serializer.cache_enabled?
- end
-
- test 'the fragment cached serializer has fragment_cache_enabled?' do
- assert @fragment_cached_serializer.fragment_cache_enabled?
- end
- end
-
- class PerformCachingFalse < CachingConfigurationTest
- setup do
- # Let's make that Rails app and initialize it!
- make_basic_app do |app|
- app.config.action_controller.perform_caching = false
- app.config.action_controller.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
- end
- controller_cache_store # Force ActiveSupport.on_load(:action_controller) to run
- end
-
- test 'it sets perform_caching to false on AMS.config and serializers' do
- refute Rails.configuration.action_controller.perform_caching
- refute ActiveModelSerializers.config.perform_caching
- refute ActiveModel::Serializer.perform_caching?
- refute @cached_serializer.perform_caching?
- refute @non_cached_serializer.perform_caching?
- refute @fragment_cached_serializer.perform_caching?
- end
-
- test 'it sets the AMS.config.cache_store to the controller cache_store' do
- assert_equal controller_cache_store, ActiveSupport::Cache::MemoryStore
- assert_equal controller_cache_store, ActiveModelSerializers.config.cache_store.class
- end
-
- test 'it sets the cached serializer cache_store to the ActionController::Base.cache_store' do
- assert_equal ActiveSupport::Cache::NullStore, @cached_serializer._cache.class
- assert_equal controller_cache_store, @cached_serializer.cache_store.class
- assert_equal ActiveSupport::Cache::MemoryStore, @cached_serializer._cache.class
- end
-
- test 'the cached serializer does not have cache_enabled?' do
- refute @cached_serializer.cache_enabled?
- end
-
- test 'the cached serializer does not have fragment_cache_enabled?' do
- refute @cached_serializer.fragment_cache_enabled?
- end
-
- test 'the non-cached serializer cache_store is nil' do
- assert_nil @non_cached_serializer._cache
- assert_nil @non_cached_serializer.cache_store
- assert_nil @non_cached_serializer._cache
- end
-
- test 'the non-cached serializer does not have cache_enabled?' do
- refute @non_cached_serializer.cache_enabled?
- end
-
- test 'the non-cached serializer does not have fragment_cache_enabled?' do
- refute @non_cached_serializer.fragment_cache_enabled?
- end
-
- test 'it sets the fragment cached serializer cache_store to the ActionController::Base.cache_store' do
- assert_equal ActiveSupport::Cache::NullStore, @fragment_cached_serializer._cache.class
- assert_equal controller_cache_store, @fragment_cached_serializer.cache_store.class
- assert_equal ActiveSupport::Cache::MemoryStore, @fragment_cached_serializer._cache.class
- end
-
- test 'the fragment cached serializer does not have cache_enabled?' do
- refute @fragment_cached_serializer.cache_enabled?
- end
-
- test 'the fragment cached serializer does not have fragment_cache_enabled?' do
- refute @fragment_cached_serializer.fragment_cache_enabled?
- end
- end
-
- def controller_cache_store
- ActionController::Base.cache_store.class
- end
-end
diff --git a/test/serializers/configuration_test.rb b/test/serializers/configuration_test.rb
deleted file mode 100644
index 2c5f922f..00000000
--- a/test/serializers/configuration_test.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class ConfigurationTest < ActiveSupport::TestCase
- def test_collection_serializer
- assert_equal ActiveModel::Serializer::CollectionSerializer, ActiveModelSerializers.config.collection_serializer
- end
-
- def test_array_serializer
- assert_equal ActiveModel::Serializer::CollectionSerializer, ActiveModelSerializers.config.array_serializer
- end
-
- def test_setting_array_serializer_sets_collection_serializer
- config = ActiveModelSerializers.config
- old_config = config.dup
- begin
- assert_equal ActiveModel::Serializer::CollectionSerializer, config.collection_serializer
- config.array_serializer = :foo
- assert_equal config.array_serializer, :foo
- assert_equal config.collection_serializer, :foo
- ensure
- ActiveModelSerializers.config.replace(old_config)
- end
- end
-
- def test_default_adapter
- assert_equal :attributes, ActiveModelSerializers.config.adapter
- end
- end
- end
-end
diff --git a/test/serializers/fieldset_test.rb b/test/serializers/fieldset_test.rb
deleted file mode 100644
index 5b99d57a..00000000
--- a/test/serializers/fieldset_test.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class FieldsetTest < ActiveSupport::TestCase
- def test_fieldset_with_hash
- fieldset = ActiveModel::Serializer::Fieldset.new('post' => %w(id title), 'comment' => ['body'])
- expected = { post: [:id, :title], comment: [:body] }
-
- assert_equal(expected, fieldset.fields)
- end
- end
- end
-end
diff --git a/test/serializers/meta_test.rb b/test/serializers/meta_test.rb
deleted file mode 100644
index 64209321..00000000
--- a/test/serializers/meta_test.rb
+++ /dev/null
@@ -1,202 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class MetaTest < ActiveSupport::TestCase
- def setup
- @blog = Blog.new(id: 1,
- name: 'AMS Hints',
- writer: Author.new(id: 2, name: 'Steve'),
- articles: [Post.new(id: 3, title: 'AMS')])
- end
-
- def test_meta_is_present_with_root
- actual = ActiveModelSerializers::SerializableResource.new(
- @blog,
- adapter: :json,
- serializer: AlternateBlogSerializer,
- meta: { total: 10 }
- ).as_json
- expected = {
- blog: {
- id: 1,
- title: 'AMS Hints'
- },
- 'meta' => {
- total: 10
- }
- }
- assert_equal(expected, actual)
- end
-
- def test_meta_is_not_included_when_blank
- actual = ActiveModelSerializers::SerializableResource.new(
- @blog,
- adapter: :json,
- serializer: AlternateBlogSerializer,
- meta: {}
- ).as_json
- expected = {
- blog: {
- id: 1,
- title: 'AMS Hints'
- }
- }
- assert_equal(expected, actual)
- end
-
- def test_meta_is_not_included_when_empty_string
- actual = ActiveModelSerializers::SerializableResource.new(
- @blog,
- adapter: :json,
- serializer: AlternateBlogSerializer,
- meta: ''
- ).as_json
- expected = {
- blog: {
- id: 1,
- title: 'AMS Hints'
- }
- }
- assert_equal(expected, actual)
- end
-
- def test_meta_is_not_included_when_root_is_missing
- actual = ActiveModelSerializers::SerializableResource.new(
- @blog,
- adapter: :attributes,
- serializer: AlternateBlogSerializer,
- meta: { total: 10 }
- ).as_json
- expected = {
- id: 1,
- title: 'AMS Hints'
- }
- assert_equal(expected, actual)
- end
-
- def test_meta_key_is_used
- actual = ActiveModelSerializers::SerializableResource.new(
- @blog,
- adapter: :json,
- serializer: AlternateBlogSerializer,
- meta: { total: 10 },
- meta_key: 'haha_meta'
- ).as_json
- expected = {
- blog: {
- id: 1,
- title: 'AMS Hints'
- },
- 'haha_meta' => {
- total: 10
- }
- }
- assert_equal(expected, actual)
- end
-
- def test_meta_key_is_not_used_with_json_api
- actual = ActiveModelSerializers::SerializableResource.new(
- @blog,
- adapter: :json_api,
- serializer: AlternateBlogSerializer,
- meta: { total: 10 },
- meta_key: 'haha_meta'
- ).as_json
- expected = {
- data: {
- id: '1',
- type: 'blogs',
- attributes: { title: 'AMS Hints' }
- },
- meta: { total: 10 }
- }
- assert_equal(expected, actual)
- end
-
- def test_meta_key_is_not_present_when_empty_hash_with_json_api
- actual = ActiveModelSerializers::SerializableResource.new(
- @blog,
- adapter: :json_api,
- serializer: AlternateBlogSerializer,
- meta: {}
- ).as_json
- expected = {
- data: {
- id: '1',
- type: 'blogs',
- attributes: { title: 'AMS Hints' }
- }
- }
- assert_equal(expected, actual)
- end
-
- def test_meta_key_is_not_present_when_empty_string_with_json_api
- actual = ActiveModelSerializers::SerializableResource.new(
- @blog,
- adapter: :json_api,
- serializer: AlternateBlogSerializer,
- meta: ''
- ).as_json
- expected = {
- data: {
- id: '1',
- type: 'blogs',
- attributes: { title: 'AMS Hints' }
- }
- }
- assert_equal(expected, actual)
- end
-
- def test_meta_is_not_present_on_arrays_without_root
- actual = ActiveModelSerializers::SerializableResource.new(
- [@blog],
- adapter: :attributes,
- meta: { total: 10 }
- ).as_json
- expected = [{
- id: 1,
- name: 'AMS Hints',
- writer: {
- id: 2,
- name: 'Steve'
- },
- articles: [{
- id: 3,
- title: 'AMS',
- body: nil
- }]
- }]
- assert_equal(expected, actual)
- end
-
- def test_meta_is_present_on_arrays_with_root
- actual = ActiveModelSerializers::SerializableResource.new(
- [@blog],
- adapter: :json,
- meta: { total: 10 },
- meta_key: 'haha_meta'
- ).as_json
- expected = {
- blogs: [{
- id: 1,
- name: 'AMS Hints',
- writer: {
- id: 2,
- name: 'Steve'
- },
- articles: [{
- id: 3,
- title: 'AMS',
- body: nil
- }]
- }],
- 'haha_meta' => {
- total: 10
- }
- }
- assert_equal(expected, actual)
- end
- end
- end
-end
diff --git a/test/serializers/options_test.rb b/test/serializers/options_test.rb
deleted file mode 100644
index 009388e3..00000000
--- a/test/serializers/options_test.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class OptionsTest < ActiveSupport::TestCase
- class ModelWithOptions < ActiveModelSerializers::Model
- attributes :name, :description
- end
- class ModelWithOptionsSerializer < ActiveModel::Serializer
- attributes :name, :description
-
- def arguments_passed_in?
- instance_options[:my_options] == :accessible
- end
- end
-
- setup do
- @model_with_options = ModelWithOptions.new(name: 'Name 1', description: 'Description 1')
- end
-
- def test_options_are_accessible
- model_with_options_serializer = ModelWithOptionsSerializer.new(@model_with_options, my_options: :accessible)
- assert model_with_options_serializer.arguments_passed_in?
- end
-
- def test_no_option_is_passed_in
- model_with_options_serializer = ModelWithOptionsSerializer.new(@model_with_options)
- refute model_with_options_serializer.arguments_passed_in?
- end
- end
- end
-end
diff --git a/test/serializers/read_attribute_for_serialization_test.rb b/test/serializers/read_attribute_for_serialization_test.rb
deleted file mode 100644
index 02911c0e..00000000
--- a/test/serializers/read_attribute_for_serialization_test.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class ReadAttributeForSerializationTest < ActiveSupport::TestCase
- # https://github.com/rails-api/active_model_serializers/issues/1653
- class Parent < ActiveModelSerializers::Model
- attributes :id
- end
- class Child < Parent
- attributes :name
- end
- class ParentSerializer < ActiveModel::Serializer
- attributes :$id
-
- define_method(:$id) do
- object.id
- end
- end
- class ChildSerializer < ParentSerializer
- attributes :name
- end
-
- def test_child_serializer_calls_dynamic_method_in_parent_serializer
- parent = ParentSerializer.new(Parent.new(id: 5))
- child = ChildSerializer.new(Child.new(id: 6, name: 'Child'))
- assert_equal 5, parent.read_attribute_for_serialization(:$id)
- assert_equal 6, child.read_attribute_for_serialization(:$id)
- end
-
- # https://github.com/rails-api/active_model_serializers/issues/1658
- class ErrorResponse < ActiveModelSerializers::Model
- attributes :error
- end
- class ApplicationSerializer < ActiveModel::Serializer
- attributes :status
-
- def status
- object.try(:errors).blank? && object.try(:error).blank?
- end
- end
- class ErrorResponseSerializer < ApplicationSerializer
- attributes :error
- end
- class ErrorResponseWithSuperSerializer < ApplicationSerializer
- attributes :error
-
- def success
- super
- end
- end
-
- def test_child_serializer_with_error_attribute
- error = ErrorResponse.new(error: 'i have an error')
- serializer = ErrorResponseSerializer.new(error)
- serializer_with_super = ErrorResponseWithSuperSerializer.new(error)
- assert_equal false, serializer.read_attribute_for_serialization(:status)
- assert_equal false, serializer_with_super.read_attribute_for_serialization(:status)
- end
-
- def test_child_serializer_with_errors
- error = ErrorResponse.new
- error.errors.add(:invalid, 'i am not valid')
- serializer = ErrorResponseSerializer.new(error)
- serializer_with_super = ErrorResponseWithSuperSerializer.new(error)
- assert_equal false, serializer.read_attribute_for_serialization(:status)
- assert_equal false, serializer_with_super.read_attribute_for_serialization(:status)
- end
-
- def test_child_serializer_no_error_attribute_or_errors
- error = ErrorResponse.new
- serializer = ErrorResponseSerializer.new(error)
- serializer_with_super = ErrorResponseWithSuperSerializer.new(error)
- assert_equal true, serializer.read_attribute_for_serialization(:status)
- assert_equal true, serializer_with_super.read_attribute_for_serialization(:status)
- end
- end
- end
-end
diff --git a/test/serializers/reflection_test.rb b/test/serializers/reflection_test.rb
deleted file mode 100644
index 11cb154b..00000000
--- a/test/serializers/reflection_test.rb
+++ /dev/null
@@ -1,427 +0,0 @@
-require 'test_helper'
-module ActiveModel
- class Serializer
- class ReflectionTest < ActiveSupport::TestCase
- class Blog < ActiveModelSerializers::Model
- attributes :id
- end
- class BlogSerializer < ActiveModel::Serializer
- type 'blog'
- attributes :id
- end
-
- setup do
- @expected_meta = { id: 1 }
- @expected_links = { self: 'no_uri_validation' }
- @empty_links = {}
- model_attributes = { blog: Blog.new(@expected_meta) }
- @model = Class.new(ActiveModelSerializers::Model) do
- attributes(*model_attributes.keys)
-
- def self.name
- 'TestModel'
- end
- end.new(model_attributes)
- @instance_options = {}
- end
-
- def evaluate_association_value(association)
- association.lazy_association.eval_reflection_block
- end
-
- # TODO: Remaining tests
- # test_reflection_value_block_with_scope
- # test_reflection_value_uses_serializer_instance_method
- # test_reflection_excluded_eh_blank_is_false
- # test_reflection_excluded_eh_if
- # test_reflection_excluded_eh_unless
- # test_evaluate_condition_symbol_serializer_method
- # test_evaluate_condition_string_serializer_method
- # test_evaluate_condition_proc
- # test_evaluate_condition_proc_yields_serializer
- # test_evaluate_condition_other
- # test_options_key
- # test_options_polymorphic
- # test_options_serializer
- # test_options_virtual_value
- # test_options_namespace
-
- def test_reflection_value
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
-
- # Assert
- assert_nil reflection.block
- assert_equal Serializer.config.include_data_default, reflection.options.fetch(:include_data_setting)
- assert_equal true, reflection.options.fetch(:include_data_setting)
-
- include_slice = :does_not_matter
- assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
- end
-
- def test_reflection_value_block
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- object.blog
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
-
- # Assert
- assert_respond_to reflection.block, :call
- assert_equal Serializer.config.include_data_default, reflection.options.fetch(:include_data_setting)
- assert_equal true, reflection.options.fetch(:include_data_setting)
-
- include_slice = :does_not_matter
- assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
- end
-
- def test_reflection_value_block_with_explicit_include_data_true
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- include_data true
- object.blog
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
-
- # Assert
- assert_respond_to reflection.block, :call
- assert_equal Serializer.config.include_data_default, reflection.options.fetch(:include_data_setting)
- assert_equal true, reflection.options.fetch(:include_data_setting)
-
- include_slice = :does_not_matter
- assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
- end
-
- def test_reflection_value_block_with_include_data_false_mutates_the_reflection_include_data
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- include_data false
- object.blog
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
-
- # Assert
- assert_respond_to reflection.block, :call
- assert_equal true, reflection.options.fetch(:include_data_setting)
- include_slice = :does_not_matter
- assert_nil reflection.send(:value, serializer_instance, include_slice)
- assert_equal false, reflection.options.fetch(:include_data_setting)
- end
-
- def test_reflection_value_block_with_include_data_if_sideloaded_included_mutates_the_reflection_include_data
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- include_data :if_sideloaded
- object.blog
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
-
- # Assert
- assert_respond_to reflection.block, :call
- assert_equal true, reflection.options.fetch(:include_data_setting)
- include_slice = {}
- assert_nil reflection.send(:value, serializer_instance, include_slice)
- assert_equal :if_sideloaded, reflection.options.fetch(:include_data_setting)
- end
-
- def test_reflection_value_block_with_include_data_if_sideloaded_excluded_mutates_the_reflection_include_data
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- include_data :if_sideloaded
- object.blog
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
-
- # Assert
- assert_respond_to reflection.block, :call
- assert_equal true, reflection.options.fetch(:include_data_setting)
- include_slice = { blog: :does_not_matter }
- assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
- assert_equal :if_sideloaded, reflection.options.fetch(:include_data_setting)
- end
-
- def test_reflection_block_with_link_mutates_the_reflection_links
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- link :self, 'no_uri_validation'
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
- assert_equal @empty_links, reflection.options.fetch(:links)
-
- # Build Association
- association = reflection.build_association(serializer_instance, @instance_options)
-
- # Assert association links empty when not yet evaluated
- assert_equal @empty_links, reflection.options.fetch(:links)
- assert_equal @empty_links, association.links
-
- evaluate_association_value(association)
-
- assert_equal @expected_links, association.links
- assert_equal @expected_links, reflection.options.fetch(:links)
- end
-
- def test_reflection_block_with_link_block_mutates_the_reflection_links
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- link :self do
- 'no_uri_validation'
- end
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
- assert_equal @empty_links, reflection.options.fetch(:links)
-
- # Build Association
- association = reflection.build_association(serializer_instance, @instance_options)
-
- # Assert association links empty when not yet evaluated
- assert_equal @empty_links, association.links
-
- evaluate_association_value(association)
-
- # Assert before instance_eval link
- link = association.links.fetch(:self)
- assert_respond_to link, :call
- assert_respond_to reflection.options.fetch(:links).fetch(:self), :call
-
- # Assert after instance_eval link
- assert_equal @expected_links.fetch(:self), reflection.instance_eval(&link)
- assert_respond_to reflection.options.fetch(:links).fetch(:self), :call
- end
-
- def test_reflection_block_with_meta_mutates_the_reflection_meta
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- meta(id: object.blog.id)
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
- assert_nil reflection.options.fetch(:meta)
-
- # Build Association
- association = reflection.build_association(serializer_instance, @instance_options)
-
- evaluate_association_value(association)
-
- assert_equal @expected_meta, association.meta
- assert_equal @expected_meta, reflection.options.fetch(:meta)
- end
-
- def test_reflection_block_with_meta_block_mutates_the_reflection_meta
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- meta do
- { id: object.blog.id }
- end
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
- assert_nil reflection.options.fetch(:meta)
-
- # Build Association
- association = reflection.build_association(serializer_instance, @instance_options)
- # Assert before instance_eval meta
-
- evaluate_association_value(association)
-
- assert_respond_to association.meta, :call
- assert_respond_to reflection.options.fetch(:meta), :call
-
- # Assert after instance_eval meta
- assert_equal @expected_meta, reflection.instance_eval(&association.meta)
- assert_respond_to reflection.options.fetch(:meta), :call
- assert_respond_to association.meta, :call
- end
-
- # rubocop:disable Metrics/AbcSize
- def test_reflection_block_with_meta_in_link_block_mutates_the_reflection_meta
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- link :self do
- meta(id: object.blog.id)
- 'no_uri_validation'
- end
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
- assert_nil reflection.options.fetch(:meta)
- assert_equal @empty_links, reflection.options.fetch(:links)
-
- # Build Association
- association = reflection.build_association(serializer_instance, @instance_options)
- # Assert before instance_eval link meta
- assert_nil association.meta
- assert_nil reflection.options.fetch(:meta)
-
- evaluate_association_value(association)
-
- link = association.links.fetch(:self)
- assert_respond_to link, :call
- assert_respond_to reflection.options.fetch(:links).fetch(:self), :call
- assert_nil reflection.options.fetch(:meta)
-
- # Assert after instance_eval link
- assert_equal 'no_uri_validation', reflection.instance_eval(&link)
- assert_equal @expected_meta, reflection.options.fetch(:meta)
- assert_equal @expected_meta, association.meta
- end
- # rubocop:enable Metrics/AbcSize
-
- # rubocop:disable Metrics/AbcSize
- def test_reflection_block_with_meta_block_in_link_block_mutates_the_reflection_meta
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- link :self do
- meta do
- { id: object.blog.id }
- end
- 'no_uri_validation'
- end
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
- assert_nil reflection.options.fetch(:meta)
-
- # Build Association
- association = reflection.build_association(serializer_instance, @instance_options)
- assert_nil association.meta
- assert_nil reflection.options.fetch(:meta)
-
- # Assert before instance_eval link
-
- evaluate_association_value(association)
-
- link = association.links.fetch(:self)
- assert_nil reflection.options.fetch(:meta)
- assert_respond_to link, :call
- assert_respond_to association.links.fetch(:self), :call
-
- # Assert after instance_eval link
- assert_equal 'no_uri_validation', reflection.instance_eval(&link)
- assert_respond_to association.links.fetch(:self), :call
- # Assert before instance_eval link meta
- assert_respond_to reflection.options.fetch(:meta), :call
- assert_respond_to association.meta, :call
-
- # Assert after instance_eval link meta
- assert_equal @expected_meta, reflection.instance_eval(&reflection.options.fetch(:meta))
- assert_respond_to association.meta, :call
- end
- # rubocop:enable Metrics/AbcSize
-
- def test_no_href_in_vanilla_reflection
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- link :self do
- href 'no_uri_validation'
- end
- end
- end
- serializer_instance = serializer_class.new(@model, @instance_options)
-
- # Get Reflection
- reflection = serializer_class._reflections.fetch(:blog)
- assert_equal @empty_links, reflection.options.fetch(:links)
-
- # Build Association
- association = reflection.build_association(serializer_instance, @instance_options)
- # Assert before instance_eval link
-
- evaluate_association_value(association)
-
- link = association.links.fetch(:self)
- assert_respond_to link, :call
-
- # Assert after instance_eval link
- exception = assert_raise(NoMethodError) do
- reflection.instance_eval(&link)
- end
- assert_match(/undefined method `href'/, exception.message)
- end
-
- # rubocop:disable Metrics/AbcSize
- def test_mutating_reflection_block_is_not_thread_safe
- serializer_class = Class.new(ActiveModel::Serializer) do
- has_one :blog do
- meta(id: object.blog.id)
- end
- end
- model1_meta = @expected_meta
- # Evaluate reflection meta for model with id 1
- serializer_instance = serializer_class.new(@model, @instance_options)
- reflection = serializer_class._reflections.fetch(:blog)
- assert_nil reflection.options.fetch(:meta)
- association = reflection.build_association(serializer_instance, @instance_options)
-
- evaluate_association_value(association)
-
- assert_equal model1_meta, association.meta
- assert_equal model1_meta, reflection.options.fetch(:meta)
-
- model2_meta = @expected_meta.merge(id: 2)
- # Evaluate reflection meta for model with id 2
- @model.blog.id = 2
- assert_equal 2, @model.blog.id # sanity check
- serializer_instance = serializer_class.new(@model, @instance_options)
- reflection = serializer_class._reflections.fetch(:blog)
-
- # WARN: Thread-safety issue
- # Before the reflection is evaluated, it has the value from the previous evaluation
- assert_equal model1_meta, reflection.options.fetch(:meta)
-
- association = reflection.build_association(serializer_instance, @instance_options)
-
- evaluate_association_value(association)
-
- assert_equal model2_meta, association.meta
- assert_equal model2_meta, reflection.options.fetch(:meta)
- end
- # rubocop:enable Metrics/AbcSize
- end
- end
-end
diff --git a/test/serializers/root_test.rb b/test/serializers/root_test.rb
deleted file mode 100644
index 5bd4cdc3..00000000
--- a/test/serializers/root_test.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class RootTest < ActiveSupport::TestCase
- def setup
- @virtual_value = VirtualValue.new(id: 1)
- end
-
- def test_overwrite_root
- serializer = VirtualValueSerializer.new(@virtual_value, root: 'smth')
- assert_equal('smth', serializer.json_key)
- end
-
- def test_underscore_in_root
- serializer = VirtualValueSerializer.new(@virtual_value)
- assert_equal('virtual_value', serializer.json_key)
- end
- end
- end
-end
diff --git a/test/serializers/serialization_test.rb b/test/serializers/serialization_test.rb
deleted file mode 100644
index 3c1884e6..00000000
--- a/test/serializers/serialization_test.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-module ActiveModel
- class Serializer
- class SerializationTest < ActiveSupport::TestCase
- class Blog < ActiveModelSerializers::Model
- attributes :id, :name, :authors
- end
- class Author < ActiveModelSerializers::Model
- attributes :id, :name
- end
- class BlogSerializer < ActiveModel::Serializer
- attributes :id
- attribute :name, key: :title
-
- has_many :authors
- end
- class AuthorSerializer < ActiveModel::Serializer
- attributes :id, :name
- end
-
- setup do
- @authors = [Author.new(id: 1, name: 'Blog Author')]
- @blog = Blog.new(id: 2, name: 'The Blog', authors: @authors)
- @serializer_instance = BlogSerializer.new(@blog)
- @serializable = ActiveModelSerializers::SerializableResource.new(@blog, serializer: BlogSerializer, adapter: :attributes)
- @expected_hash = { id: 2, title: 'The Blog', authors: [{ id: 1, name: 'Blog Author' }] }
- @expected_json = '{"id":2,"title":"The Blog","authors":[{"id":1,"name":"Blog Author"}]}'
- end
-
- test '#serializable_hash is the same as generated by the attributes adapter' do
- assert_equal @serializable.serializable_hash, @serializer_instance.serializable_hash
- assert_equal @expected_hash, @serializer_instance.serializable_hash
- end
-
- test '#as_json is the same as generated by the attributes adapter' do
- assert_equal @serializable.as_json, @serializer_instance.as_json
- assert_equal @expected_hash, @serializer_instance.as_json
- end
-
- test '#to_json is the same as generated by the attributes adapter' do
- assert_equal @serializable.to_json, @serializer_instance.to_json
- assert_equal @expected_json, @serializer_instance.to_json
- end
-
- test '#to_h is an alias for #serializable_hash' do
- assert_equal @serializable.serializable_hash, @serializer_instance.to_h
- assert_equal @expected_hash, @serializer_instance.to_h
- end
-
- test '#to_hash is an alias for #serializable_hash' do
- assert_equal @serializable.serializable_hash, @serializer_instance.to_hash
- assert_equal @expected_hash, @serializer_instance.to_hash
- end
- end
- end
-end
diff --git a/test/serializers/serializer_for_test.rb b/test/serializers/serializer_for_test.rb
deleted file mode 100644
index 9f691708..00000000
--- a/test/serializers/serializer_for_test.rb
+++ /dev/null
@@ -1,136 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class SerializerForTest < ActiveSupport::TestCase
- class CollectionSerializerTest < ActiveSupport::TestCase
- def setup
- @array = [1, 2, 3]
- @previous_collection_serializer = ActiveModelSerializers.config.collection_serializer
- end
-
- def teardown
- ActiveModelSerializers.config.collection_serializer = @previous_collection_serializer
- end
-
- def test_serializer_for_array
- serializer = ActiveModel::Serializer.serializer_for(@array)
- assert_equal ActiveModelSerializers.config.collection_serializer, serializer
- end
-
- def test_overwritten_serializer_for_array
- new_collection_serializer = Class.new
- ActiveModelSerializers.config.collection_serializer = new_collection_serializer
- serializer = ActiveModel::Serializer.serializer_for(@array)
- assert_equal new_collection_serializer, serializer
- end
- end
-
- class SerializerTest < ActiveSupport::TestCase
- module ResourceNamespace
- class Post < ::Model; end
- class Comment < ::Model; end
-
- class PostSerializer < ActiveModel::Serializer
- class CommentSerializer < ActiveModel::Serializer
- end
- end
- end
-
- class MyProfile < Profile
- end
-
- class CustomProfile
- def serializer_class
- ProfileSerializer
- end
- end
-
- class Tweet < ::Model; end
- TweetSerializer = Class.new
-
- def setup
- @profile = Profile.new
- @my_profile = MyProfile.new
- @custom_profile = CustomProfile.new
- @model = ::Model.new
- @tweet = Tweet.new
- end
-
- def test_serializer_for_non_ams_serializer
- serializer = ActiveModel::Serializer.serializer_for(@tweet)
- assert_nil serializer
- end
-
- def test_serializer_for_existing_serializer
- serializer = ActiveModel::Serializer.serializer_for(@profile)
- assert_equal ProfileSerializer, serializer
- end
-
- def test_serializer_for_existing_serializer_with_lookup_disabled
- serializer = with_serializer_lookup_disabled do
- ActiveModel::Serializer.serializer_for(@profile)
- end
- assert_nil serializer
- end
-
- def test_serializer_for_not_existing_serializer
- serializer = ActiveModel::Serializer.serializer_for(@model)
- assert_nil serializer
- end
-
- def test_serializer_inherited_serializer
- serializer = ActiveModel::Serializer.serializer_for(@my_profile)
- assert_equal ProfileSerializer, serializer
- end
-
- def test_serializer_inherited_serializer_with_lookup_disabled
- serializer = with_serializer_lookup_disabled do
- ActiveModel::Serializer.serializer_for(@my_profile)
- end
- assert_nil serializer
- end
-
- def test_serializer_custom_serializer
- serializer = ActiveModel::Serializer.serializer_for(@custom_profile)
- assert_equal ProfileSerializer, serializer
- end
-
- def test_serializer_custom_serializer_with_lookup_disabled
- serializer = with_serializer_lookup_disabled do
- ActiveModel::Serializer.serializer_for(@custom_profile)
- end
- assert_equal ProfileSerializer, serializer
- end
-
- def test_serializer_for_namespaced_resource
- post = ResourceNamespace::Post.new
- serializer = ActiveModel::Serializer.serializer_for(post)
- assert_equal ResourceNamespace::PostSerializer, serializer
- end
-
- def test_serializer_for_namespaced_resource_with_lookup_disabled
- post = ResourceNamespace::Post.new
- serializer = with_serializer_lookup_disabled do
- ActiveModel::Serializer.serializer_for(post)
- end
- assert_nil serializer
- end
-
- def test_serializer_for_nested_resource
- comment = ResourceNamespace::Comment.new
- serializer = ResourceNamespace::PostSerializer.serializer_for(comment)
- assert_equal ResourceNamespace::PostSerializer::CommentSerializer, serializer
- end
-
- def test_serializer_for_nested_resource_with_lookup_disabled
- comment = ResourceNamespace::Comment.new
- serializer = with_serializer_lookup_disabled do
- ResourceNamespace::PostSerializer.serializer_for(comment)
- end
- assert_nil serializer
- end
- end
- end
- end
-end
diff --git a/test/serializers/serializer_for_with_namespace_test.rb b/test/serializers/serializer_for_with_namespace_test.rb
deleted file mode 100644
index 5c6e3e5e..00000000
--- a/test/serializers/serializer_for_with_namespace_test.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-require 'test_helper'
-
-module ActiveModel
- class Serializer
- class SerializerForWithNamespaceTest < ActiveSupport::TestCase
- class Book < ::Model
- attributes :title, :author_name
- associations :publisher, :pages
- end
- class Page < ::Model; attributes :number, :text end
- class Publisher < ::Model; attributes :name end
-
- module Api
- module V3
- class BookSerializer < ActiveModel::Serializer
- attributes :title, :author_name
-
- has_many :pages
- belongs_to :publisher
- end
-
- class PageSerializer < ActiveModel::Serializer
- attributes :number, :text
- end
-
- class PublisherSerializer < ActiveModel::Serializer
- attributes :name
- end
- end
- end
-
- class BookSerializer < ActiveModel::Serializer
- attributes :title, :author_name
- end
- test 'resource without a namespace' do
- book = Book.new(title: 'A Post', author_name: 'hello')
-
- # TODO: this should be able to pull up this serializer without explicitly specifying the serializer
- # currently, with no options, it still uses the Api::V3 serializer
- result = ActiveModelSerializers::SerializableResource.new(book, serializer: BookSerializer).serializable_hash
-
- expected = { title: 'A Post', author_name: 'hello' }
- assert_equal expected, result
- end
-
- test 'resource with namespace' do
- book = Book.new(title: 'A Post', author_name: 'hi')
-
- result = ActiveModelSerializers::SerializableResource.new(book, namespace: Api::V3).serializable_hash
-
- expected = { title: 'A Post', author_name: 'hi', pages: nil, publisher: nil }
- assert_equal expected, result
- end
-
- test 'has_many with nested serializer under the namespace' do
- page = Page.new(number: 1, text: 'hello')
- book = Book.new(title: 'A Post', author_name: 'hi', pages: [page])
-
- result = ActiveModelSerializers::SerializableResource.new(book, namespace: Api::V3).serializable_hash
-
- expected = {
- title: 'A Post', author_name: 'hi',
- publisher: nil,
- pages: [{
- number: 1, text: 'hello'
- }]
- }
- assert_equal expected, result
- end
-
- test 'belongs_to with nested serializer under the namespace' do
- publisher = Publisher.new(name: 'Disney')
- book = Book.new(title: 'A Post', author_name: 'hi', publisher: publisher)
-
- result = ActiveModelSerializers::SerializableResource.new(book, namespace: Api::V3).serializable_hash
-
- expected = {
- title: 'A Post', author_name: 'hi',
- pages: nil,
- publisher: {
- name: 'Disney'
- }
- }
- assert_equal expected, result
- end
- end
- end
-end
diff --git a/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json b/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json
deleted file mode 100644
index 9474c509..00000000
--- a/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "properties": {
- "name" : { "type" : "string" },
- "description" : { "type" : "string" }
- }
-}
diff --git a/test/support/isolated_unit.rb b/test/support/isolated_unit.rb
deleted file mode 100644
index 26948d4a..00000000
--- a/test/support/isolated_unit.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-# https://github.com/rails/rails/blob/v5.0.0.beta1/railties/test/isolation/abstract_unit.rb
-
-# Usage Example:
-#
-# require 'support/isolated_unit'
-#
-# class RailtieTest < ActiveSupport::TestCase
-# include ActiveSupport::Testing::Isolation
-#
-# class WithRailsDefinedOnLoad < RailtieTest
-# setup do
-# require 'rails'
-# require 'active_model_serializers'
-# make_basic_app
-# end
-#
-# # some tests
-# end
-#
-# class WithoutRailsDefinedOnLoad < RailtieTest
-# setup do
-# require 'active_model_serializers'
-# make_basic_app
-# end
-#
-# # some tests
-# end
-# end
-#
-# Note:
-# It is important to keep this file as light as possible
-# the goal for tests that require this is to test booting up
-# rails from an empty state, so anything added here could
-# hide potential failures
-#
-# It is also good to know what is the bare minimum to get
-# Rails booted up.
-require 'bundler/setup' unless defined?(Bundler)
-require 'active_support'
-require 'active_support/core_ext/string/access'
-
-# These files do not require any others and are needed
-# to run the tests
-require 'active_support/testing/autorun'
-require 'active_support/testing/isolation'
-
-module TestHelpers
- module Generation
- module_function
-
- # Make a very basic app, without creating the whole directory structure.
- # Is faster and simpler than generating a Rails app in a temp directory
- def make_basic_app
- require 'rails'
- require 'action_controller/railtie'
-
- @app = Class.new(Rails::Application) do
- config.eager_load = false
- config.session_store :cookie_store, key: '_myapp_session'
- config.active_support.deprecation = :log
- config.active_support.test_order = :parallel
- ActiveSupport::TestCase.respond_to?(:test_order=) && ActiveSupport::TestCase.test_order = :parallel
- config.root = File.dirname(__FILE__)
- config.log_level = :info
- # Set a fake logger to avoid creating the log directory automatically
- fake_logger = Logger.new(nil)
- config.logger = fake_logger
- Rails.application.routes.default_url_options = { host: 'example.com' }
- end
- @app.respond_to?(:secrets) && @app.secrets.secret_key_base = '3b7cd727ee24e8444053437c36cc66c4'
-
- yield @app if block_given?
- @app.initialize!
- end
- end
-end
-
-module ActiveSupport
- class TestCase
- include TestHelpers::Generation
- end
-end
diff --git a/test/support/rails5_shims.rb b/test/support/rails5_shims.rb
deleted file mode 100644
index 03a036da..00000000
--- a/test/support/rails5_shims.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-module Rails5Shims
- module ControllerTests
- # https://github.com/rails/rails/blob/b217354/actionpack/lib/action_controller/test_case.rb
- REQUEST_KWARGS = [:params, :headers, :session, :flash, :method, :body, :xhr].freeze
-
- def get(path, *args)
- fold_kwargs!(args)
- super
- end
-
- def post(path, *args)
- fold_kwargs!(args)
- super
- end
-
- def patch(path, *args)
- fold_kwargs!(args)
- super
- end
-
- def put(path, *args)
- fold_kwargs!(args)
- super
- end
-
- # Fold kwargs from test request into args
- # Band-aid for DEPRECATION WARNING
- def fold_kwargs!(args)
- hash = args && args[0]
- return unless hash.respond_to?(:key)
- Rails5Shims::ControllerTests::REQUEST_KWARGS.each do |kwarg|
- next unless hash.key?(kwarg)
- value = hash.delete(kwarg)
- if value.is_a? String
- args.insert(0, value)
- else
- hash.merge! value
- end
- end
- end
-
- # Uncomment for debugging where the kwargs warnings come from
- # def non_kwarg_request_warning
- # super.tap do
- # STDOUT.puts caller[2..3]
- # end
- # end
- end
-end
-if Rails::VERSION::MAJOR < 5
- ActionController::TestCase.send :include, Rails5Shims::ControllerTests
- ActionDispatch::IntegrationTest.send :include, Rails5Shims::ControllerTests
-end
diff --git a/test/support/rails_app.rb b/test/support/rails_app.rb
deleted file mode 100644
index 43324b78..00000000
--- a/test/support/rails_app.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-require 'support/isolated_unit'
-module ActiveModelSerializers
- RailsApplication = TestHelpers::Generation.make_basic_app do |app|
- app.configure do
- config.secret_key_base = 'abc123'
- config.active_support.test_order = :random
- config.action_controller.perform_caching = true
- config.action_controller.cache_store = :memory_store
-
- config.filter_parameters += [:password]
- end
-
- app.routes.default_url_options = { host: 'example.com' }
- end
-end
-
-Routes = ActionDispatch::Routing::RouteSet.new
-Routes.draw do
- get ':controller(/:action(/:id))'
- get ':controller(/:action)'
-end
-ActionController::Base.send :include, Routes.url_helpers
-ActionController::TestCase.class_eval do
- def setup
- @routes = Routes
- end
-end
-
-# ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../test/dummy/db/migrate", __FILE__)]
-# ActiveRecord::Migrator.migrations_paths << File.expand_path('../../db/migrate', __FILE__)
-#
-# Load fixtures from the engine
-# if ActiveSupport::TestCase.respond_to?(:fixture_path=)
-# ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
-# ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path
-# ActiveSupport::TestCase.file_fixture_path = ActiveSupport::TestCase.fixture_path + "/files"
-# ActiveSupport::TestCase.fixtures :all
-# end
diff --git a/test/support/schemas/active_model_serializers/test/schema_test/my/index.json b/test/support/schemas/active_model_serializers/test/schema_test/my/index.json
deleted file mode 100644
index 9474c509..00000000
--- a/test/support/schemas/active_model_serializers/test/schema_test/my/index.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "properties": {
- "name" : { "type" : "string" },
- "description" : { "type" : "string" }
- }
-}
diff --git a/test/support/schemas/active_model_serializers/test/schema_test/my/show.json b/test/support/schemas/active_model_serializers/test/schema_test/my/show.json
deleted file mode 100644
index 71313665..00000000
--- a/test/support/schemas/active_model_serializers/test/schema_test/my/show.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "properties": {
- "name" : { "type" : "integer" },
- "description" : { "type" : "boolean" }
- }
-}
diff --git a/test/support/schemas/custom/show.json b/test/support/schemas/custom/show.json
deleted file mode 100644
index 29a47e15..00000000
--- a/test/support/schemas/custom/show.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "id": "file://custom/show.json#",
- "properties": {
- "name" : { "type" : "string" },
- "description" : { "type" : "string" }
- }
-}
diff --git a/test/support/schemas/hyper_schema.json b/test/support/schemas/hyper_schema.json
deleted file mode 100644
index ae1f8f33..00000000
--- a/test/support/schemas/hyper_schema.json
+++ /dev/null
@@ -1,93 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-04/hyper-schema",
- "title": "Profile",
- "description": "Profile schema",
- "stability": "prototype",
- "strictProperties": true,
- "type": [
- "object"
- ],
- "definitions": {
- "name": {
- "description": "unique name of profile",
- "readOnly": true,
- "type": [
- "string"
- ]
- },
- "description": {
- "description": "description of profile",
- "readOnly": true,
- "type": [
- "string"
- ]
- },
- "identity": {
- "anyOf": [
- {
- "$ref": "/schemata/profile#/definitions/name"
- }
- ]
- }
- },
- "links": [
- {
- "description": "Create a new profile.",
- "href": "/profiles",
- "method": "POST",
- "rel": "create",
- "schema": {
- "properties": {
- },
- "type": [
- "object"
- ]
- },
- "title": "Create"
- },
- {
- "description": "Delete an existing profile.",
- "href": "/profiles/{(%2Fschemata%2Fprofile%23%2Fdefinitions%2Fidentity)}",
- "method": "DELETE",
- "rel": "destroy",
- "title": "Delete"
- },
- {
- "description": "Info for existing profile.",
- "href": "/profiles/{(%2Fschemata%2Fprofile%23%2Fdefinitions%2Fidentity)}",
- "method": "GET",
- "rel": "self",
- "title": "Info"
- },
- {
- "description": "List existing profiles.",
- "href": "/profiles",
- "method": "GET",
- "rel": "instances",
- "title": "List"
- },
- {
- "description": "Update an existing profile.",
- "href": "/profiles/{(%2Fschemata%2Fprofile%23%2Fdefinitions%2Fidentity)}",
- "method": "PATCH",
- "rel": "update",
- "schema": {
- "properties": {
- },
- "type": [
- "object"
- ]
- },
- "title": "Update"
- }
- ],
- "properties": {
- "name": {
- "$ref": "/schemata/profile#/definitions/name"
- },
- "description": {
- "$ref": "/schemata/profile#/definitions/description"
- }
- },
- "id": "/schemata/profile"
-}
diff --git a/test/support/schemas/render_using_json_api.json b/test/support/schemas/render_using_json_api.json
deleted file mode 100644
index 1a8f8fe1..00000000
--- a/test/support/schemas/render_using_json_api.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-04/schema#",
- "id": "",
- "type": "object",
- "properties": {
- "data": {
- "id": "/data",
- "type": "object",
- "properties": {
- "id": {
- "id": "/data/id",
- "type": "string"
- },
- "type": {
- "id": "/data/type",
- "type": "string"
- },
- "attributes": {
- "id": "/data/attributes",
- "type": "object",
- "properties": {
- "name": {
- "id": "/data/attributes/name",
- "type": "string"
- },
- "description": {
- "id": "/data/attributes/description",
- "type": "string"
- }
- }
- }
- },
- "required": [
- "id",
- "type",
- "attributes"
- ]
- }
- },
- "required": [
- "data"
- ]
-}
diff --git a/test/support/schemas/simple_json_pointers.json b/test/support/schemas/simple_json_pointers.json
deleted file mode 100644
index d1a6f1eb..00000000
--- a/test/support/schemas/simple_json_pointers.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "properties": {
- "name": {
- "$ref": "file://custom/show.json#/properties/name"
- },
- "description": {
- "$ref": "file://custom/show.json#/properties/description"
- }
- }
-}
diff --git a/test/support/serialization_testing.rb b/test/support/serialization_testing.rb
deleted file mode 100644
index 524a3297..00000000
--- a/test/support/serialization_testing.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-module SerializationTesting
- def config
- ActiveModelSerializers.config
- end
-
- private
-
- def generate_cached_serializer(obj)
- ActiveModelSerializers::SerializableResource.new(obj).to_json
- end
-
- def with_namespace_separator(separator)
- original_separator = ActiveModelSerializers.config.jsonapi_namespace_separator
- ActiveModelSerializers.config.jsonapi_namespace_separator = separator
- yield
- ensure
- ActiveModelSerializers.config.jsonapi_namespace_separator = original_separator
- end
-
- def with_prepended_lookup(lookup_proc)
- original_lookup = ActiveModelSerializers.config.serializer_lookup_cahin
- ActiveModelSerializers.config.serializer_lookup_chain.unshift lookup_proc
- yield
- ensure
- ActiveModelSerializers.config.serializer_lookup_cahin = original_lookup
- end
-
- # Aliased as :with_configured_adapter to clarify that
- # this method tests the configured adapter.
- # When not testing configuration, it may be preferable
- # to pass in the +adapter+ option to ActiveModelSerializers::SerializableResource.
- # e.g ActiveModelSerializers::SerializableResource.new(resource, adapter: :json_api)
- def with_adapter(adapter)
- old_adapter = ActiveModelSerializers.config.adapter
- ActiveModelSerializers.config.adapter = adapter
- yield
- ensure
- ActiveModelSerializers.config.adapter = old_adapter
- end
- alias with_configured_adapter with_adapter
-
- def with_config(hash)
- old_config = config.dup
- ActiveModelSerializers.config.update(hash)
- yield
- ensure
- ActiveModelSerializers.config.replace(old_config)
- end
-
- def with_serializer_lookup_disabled
- original_serializer_lookup = ActiveModelSerializers.config.serializer_lookup_enabled
- ActiveModelSerializers.config.serializer_lookup_enabled = false
- yield
- ensure
- ActiveModelSerializers.config.serializer_lookup_enabled = original_serializer_lookup
- end
-
- def serializable(resource, options = {})
- ActiveModelSerializers::SerializableResource.new(resource, options)
- end
-end
-
-module Minitest
- class Test
- def before_setup
- ActionController::Base.cache_store.clear
- end
-
- include SerializationTesting
- end
-end
diff --git a/test/test_helper.rb b/test/test_helper.rb
deleted file mode 100644
index 294fa33c..00000000
--- a/test/test_helper.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-# Configure Rails Environment
-ENV['RAILS_ENV'] = 'test'
-require 'bundler/setup'
-
-begin
- require 'simplecov'
- AppCoverage.start
-rescue LoadError
- STDERR.puts 'Running without SimpleCov'
-end
-
-require 'pry'
-require 'timecop'
-require 'rails'
-require 'action_controller'
-require 'action_controller/test_case'
-require 'action_controller/railtie'
-require 'active_model_serializers'
-# For now, we only restrict the options to serializable_hash/as_json/to_json
-# in tests, to ensure developers don't add any unsupported options.
-# There's no known benefit, at this time, to having the filtering run in
-# production when the excluded options would simply not be used.
-#
-# However, for documentation purposes, the constant
-# ActiveModel::Serializer::SERIALIZABLE_HASH_VALID_KEYS is defined
-# in the Serializer.
-ActiveModelSerializers::Adapter::Base.class_eval do
- alias_method :original_serialization_options, :serialization_options
-
- def serialization_options(options)
- original_serialization_options(options)
- .slice(*ActiveModel::Serializer::SERIALIZABLE_HASH_VALID_KEYS)
- end
-end
-require 'fileutils'
-FileUtils.mkdir_p(File.expand_path('../../tmp/cache', __FILE__))
-
-gem 'minitest'
-require 'minitest'
-require 'minitest/autorun'
-Minitest.backtrace_filter = Minitest::BacktraceFilter.new
-
-module TestHelper
- module_function
-
- def silence_warnings
- original_verbose = $VERBOSE
- $VERBOSE = nil
- yield
- ensure
- $VERBOSE = original_verbose
- end
-end
-
-require 'support/rails_app'
-
-# require "rails/test_help"
-
-require 'support/serialization_testing'
-
-require 'support/rails5_shims'
-
-require 'fixtures/active_record'
-
-require 'fixtures/poro'
-
-ActiveSupport.on_load(:action_controller) do
- $action_controller_logger = ActiveModelSerializers.logger
- ActiveModelSerializers.logger = Logger.new(IO::NULL)
-end