- Setup dummy app files in `test/dummy`
- Setup dummy test server `bin/serve_dummy
- Note: Serializer caching can be completely disabled by passing in
`CACHE_ON=off bin/serve_dummy start` since Serializer#_cache is only
set at boot.
- run with
- ./bin/bench
- `bin/bench` etc adapted from ruby-bench-suite
- target files are `test/dummy/bm_*.rb`. Just add another to run it.
- benchmark cache/no cache
- remove rake dependency that loads unnecessary files
- remove git gem dependency
- Running over revisions to be added in subsequent PR
I was seeing transient failures where adapters may not be registered.
e.g. https://travis-ci.org/rails-api/active_model_serializers/builds/77735382
Since we're using the Adapter, JsonApi, and Json classes
as namespaces, some of the conventions we use for modules don't apply.
Basically, we don't want to define the class anywhere besides itself.
Otherwise, the inherited hooks may not run, and some adapters may not
be registered.
For example:
If we have a class Api `class Api; end`
And Api is also used as a namespace for `Api::Product`
And the classes are defined in different files.
In one file:
```ruby
class Api
autoload :Product
def self.inherited(subclass)
puts
p [:inherited, subclass.name]
puts
end
end
```
And in another:
```ruby
class Api
class Product < Api
def sell_sell_sell!
# TODO: sell
end
end
end
```
If we load the Api class file first, the inherited hook will be defined on the class
so that when we load the Api::Product class, we'll see the output:
```plain
[ :inherited, Api::Product]
```
However, if we load the Api::Product class first, since it defines the `Api` class
and then inherited from it, the Api file was never loaded, the hook never defined,
and thus never run.
By defining the class as `class Api::Product < Api` We ensure the the Api class
MUST be defined, and thus, the hook will be defined and run and so sunshine and unicorns.
Appendix:
The below would work, but triggers a circular reference warning.
It's also not recommended to mix require with autoload.
```ruby
require 'api'
class Api
class Product < Api
def sell_sell_sell!
# TODO: sell
end
end
end
```
This failure scenario was introduced by removing the circular reference warnings in
https://github.com/rails-api/active_model_serializers/pull/1067
Style note:
To make diffs on the adapters smalleer and easier to read, I've maintained the same
identention that was in the original file. I've decided to prefer ease of reading
the diff over style, esp. since we may later return to the preferred class declaration style.
with '#' will be ignored, and an empty message aborts the commit.
Changes:
- Introduce Adapter::get for use by Serializer.adapter
- Move Adapter-finding logic from Adapter::adapter_class into Adapter::get
Introduced interfaces:
- non-inherited methods
```ruby
ActiveModel::Serializer::Adapter.adapter_map # a Hash<adapter_name, adapter_class>
ActiveModel::Serializer::Adapter.adapters # an Array<adapter_name>
ActiveModel::Serializer::Adapter.register(name, klass) # adds an adapter to the adapter_map
ActiveModel::Serializer::Adapter.get(name_or_klass) # raises Argument error when adapter not found
```
- Automatically register adapters when subclassing
```ruby
def self.inherited(subclass)
ActiveModel::Serializer::Adapter.register(subclass.to_s.demodulize, subclass)
end
```
- Preserves subclass method `::adapter_class(adapter)`
```ruby
def self.adapter_class(adapter)
ActiveModel::Serializer::Adapter.get(adapter)
end
```
- Serializer.adapter now uses `Adapter.get(config.adapter)` rather than have duplicate logic