Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add allow_wildcard configuration #2362

Open
wants to merge 3 commits into
base: 0-10-stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Breaking changes:

Features:

- [#2362](https://github.com/rails-api/active_model_serializers/pull/2362) Add `allow_wildcard` configuration option (@Borzik)
- [#2361](https://github.com/rails-api/active_model_serializers/pull/2361) Add `ActiveModelSerializers.config.use_sha1_digests` to allow customization of the hashing algorithm used for serializer caching (@alexzherdev)

Fixes:
Expand Down
12 changes: 12 additions & 0 deletions docs/general/configuration_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ What relationships to serialize by default. Default: `'*'`, which includes one
objects. See [includes](adapters.md#included) for more info.


##### allow_wildcard

Enable wildcard `include` directives (`*`, `**`).

Possible values:

- `true` (default)
- `false`

When `false`, nested associations to be included must be explicitly specified. Note: this will override default_includes configuration as `*` include will no longer be accepted.


##### serializer_lookup_chain

Configures how serializers are searched for. By default, the lookup chain is
Expand Down
3 changes: 2 additions & 1 deletion lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ 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)
JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: config.allow_wildcard)
else
ActiveModelSerializers.default_include_directive
end
Expand Down Expand Up @@ -135,6 +135,7 @@ def config.array_serializer
end

config.default_includes = '*'
config.allow_wildcard = true
config.adapter = :attributes
config.key_transform = nil
config.jsonapi_pagination_links_enabled = true
Expand Down
2 changes: 1 addition & 1 deletion lib/active_model_serializers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def self.location_of_caller
# Memoized default include directive
# @return [JSONAPI::IncludeDirective]
def self.default_include_directive
@default_include_directive ||= JSONAPI::IncludeDirective.new(config.default_includes, allow_wildcard: true)
@default_include_directive ||= JSONAPI::IncludeDirective.new(config.default_includes, allow_wildcard: config.allow_wildcard)
end

def self.silence_warnings
Expand Down
4 changes: 2 additions & 2 deletions lib/active_model_serializers/adapter/json_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def self.fragment_cache(cached_hash, non_cached_hash, root = true)

def initialize(serializer, options = {})
super
@include_directive = JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true)
@include_directive = JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: ActiveModelSerializers.config.allow_wildcard)
@fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields))
end

Expand Down Expand Up @@ -452,7 +452,7 @@ def data_for(serializer, include_slice)
def relationships_for(serializer, requested_associations, include_slice)
include_directive = JSONAPI::IncludeDirective.new(
requested_associations,
allow_wildcard: true
allow_wildcard: ActiveModelSerializers.config.allow_wildcard
)
serializer.associations(include_directive, include_slice).each_with_object({}) do |association, hash|
hash[association.key] = Relationship.new(serializer, instance_options, association).as_json
Expand Down
78 changes: 78 additions & 0 deletions test/action_controller/json/include_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class IncludeTest < ActionController::TestCase
INCLUDE_STRING = 'posts.comments'.freeze
INCLUDE_HASH = { posts: :comments }.freeze
DEEP_INCLUDE = 'posts.comments.author'.freeze
WILDCARD_INCLUDE = '*'.freeze
DEEP_WILDCARD_INCLUDE = '**'.freeze

class IncludeTestController < ActionController::Base
def setup_data
Expand Down Expand Up @@ -57,6 +59,16 @@ def render_resource_with_deep_include
render json: @author, include: DEEP_INCLUDE, adapter: :json
end

def render_resource_with_wildcard_include
setup_data
render json: @author, include: WILDCARD_INCLUDE, adapter: :json
end

def render_resource_with_deep_wildcard_include
setup_data
render json: @author, include: DEEP_WILDCARD_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.
Expand Down Expand Up @@ -114,6 +126,48 @@ def test_render_resource_with_deep_include
assert_equal(expected_deep_include_response, response)
end

def test_render_resource_with_wildcard_include
get :render_resource_with_wildcard_include

response = JSON.parse(@response.body)

assert_equal(expected_wildcard_include_response, response)
end

def test_render_resource_with_wildcard_include_with_wildcards_disabled
with_wildcards_disabled do
get :render_resource_with_wildcard_include
end

expected = {
'author' => {
'id' => 1,
'name' => 'Steve K.'
}
}

response = JSON.parse(@response.body)

assert_equal(expected, response)
end

def test_render_resource_with_deep_wildcard_include_with_wildcards_disabled
with_wildcards_disabled do
get :render_resource_with_deep_wildcard_include
end

expected = {
'author' => {
'id' => 1,
'name' => 'Steve K.'
}
}

response = JSON.parse(@response.body)

assert_equal(expected, response)
end

def test_render_with_empty_default_includes
with_default_includes '' do
get :render_without_include
Expand Down Expand Up @@ -176,6 +230,22 @@ def test_render_with_includes_overrides_default_includes

private

def expected_wildcard_include_response
{
'author' => {
'id' => 1,
'name' => 'Steve K.',
'posts' => [
{
'id' => 42, 'title' => 'New Post', 'body' => 'Body'
}
],
'roles' => [],
'bio' => {}
}
}
end

def expected_include_response
{
'author' => {
Expand Down Expand Up @@ -238,6 +308,14 @@ def with_default_includes(include_directive)
clear_include_directive_cache
end

def with_wildcards_disabled
original = ActiveModelSerializers.config.allow_wildcard
ActiveModelSerializers.config.allow_wildcard = false
yield
ensure
ActiveModelSerializers.config.allow_wildcard = original
end

def clear_include_directive_cache
ActiveModelSerializers
.instance_variable_set(:@default_include_directive, nil)
Expand Down
17 changes: 17 additions & 0 deletions test/action_controller/json_api/linked_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,23 @@ def test_render_resource_with_nested_has_many_include
assert_equal expected_linked, response['included']
end

def test_render_resource_with_nested_has_many_include_with_wildcards_disabled
ActiveModel::Serializer.config.allow_wildcard = false
get '/render_resource_with_nested_has_many_include_wildcard'
ActiveModel::Serializer.config.allow_wildcard = true
response = JSON.parse(@response.body)
expected_linked = [
{
'id' => '1',
'type' => 'authors',
'attributes' => {
'name' => 'Steve K.'
}
}
]
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)
Expand Down