Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduces per-request adapter switching based on the request mime.
Browse files Browse the repository at this point in the history
Fletcher91 committed May 2, 2017

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent dff621e commit 1309f22
Showing 6 changed files with 35 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@ Breaking changes:

Features:

- [#?](https://github.com/rails-api/active_model_serializers/pull/?) Introduces per-request adapter switching based on the request mime. (@fletcher91)

Fixes:

Misc:
14 changes: 14 additions & 0 deletions docs/general/adapters.md
Original file line number Diff line number Diff line change
@@ -36,6 +36,20 @@ The `Attributes` adapter does not include a root key. It is just the serialized

Use either the `JSON` or `JSON API` adapters if you want the response document to have a root key.

To automatically switch between adapters based on the request, set the adapter to `:mime`

```ruby
# In configuration
ActiveModelSerializers.config.adapter = :mime

# In controller action
respond_to do |format|
format.json { render json: Model.first } # Uses the JSON adapter
format.json_api { render json: Model.first } # Users the JSON:API adapter
format.bug { render json: Model.first } # Will raise `UnknownAdapterError`
end
```

## Built in Adapters

### Attributes - Default
5 changes: 5 additions & 0 deletions lib/active_model_serializers/adapter.rb
Original file line number Diff line number Diff line change
@@ -19,6 +19,11 @@ def configured_adapter

def create(resource, options = {})
override = options.delete(:adapter)
context = options[:serialization_context]
format = context && context.format
if format && (override || ActiveModelSerializers.config.adapter) == :mime
override = lookup(format)
end
klass = override ? adapter_class(override) : configured_adapter
klass.new(resource, options)
end
4 changes: 3 additions & 1 deletion lib/active_model_serializers/serialization_context.rb
Original file line number Diff line number Diff line change
@@ -21,15 +21,17 @@ def default_url_options
end
end

attr_reader :request_url, :query_parameters, :key_transform
attr_reader :request_url, :query_parameters, :key_transform, :format

def initialize(*args)
options = args.extract_options!
if args.size == 1
request = args.pop
options[:format] = request.format.to_sym
options[:request_url] = request.original_url[/\A[^?]+/]
options[:query_parameters] = request.query_parameters
end
@format = options.delete(:format)
@request_url = options.delete(:request_url)
@query_parameters = options.delete(:query_parameters)
@url_helpers = options.delete(:url_helpers) || self.class.url_helpers
1 change: 1 addition & 0 deletions test/adapter/json_api/pagination_links_test.rb
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ def mock_request(query_parameters = {}, original_url = URI)
context.expect(:request_url, original_url)
context.expect(:query_parameters, query_parameters)
context.expect(:key_transform, nil)
context.expect(:format, nil)
end

def load_adapter(paginated_collection, mock_request = nil)
10 changes: 10 additions & 0 deletions test/adapter_test.rb
Original file line number Diff line number Diff line change
@@ -55,6 +55,16 @@ def test_create_adapter_with_override
assert_equal ActiveModelSerializers::Adapter::JsonApi, adapter.class
end

def test_create_adapter_with_mime
json_context = ActiveModelSerializers::SerializationContext.new(format: :json)
adapter = ActiveModelSerializers::Adapter.create(@serializer, adapter: :mime, serialization_context: json_context)
assert_equal ActiveModelSerializers::Adapter::Json, adapter.class

json_api_context = ActiveModelSerializers::SerializationContext.new(format: :json_api)
adapter = ActiveModelSerializers::Adapter.create(@serializer, adapter: :mime, serialization_context: json_api_context)
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)

0 comments on commit 1309f22

Please sign in to comment.