Skip to content

Commit 2f68ab4

Browse files
committed
Restrict serializable_hash to accepted options
1 parent aad7779 commit 2f68ab4

File tree

5 files changed

+20
-2
lines changed

5 files changed

+20
-2
lines changed

lib/active_model/serializer.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
# reified when subclassed to decorate a resource.
1919
module ActiveModel
2020
class Serializer
21+
SERIALIZABLE_HASH_VALID_KEYS = [:only, :except, :methods, :include, :root].freeze
2122
extend ActiveSupport::Autoload
2223
autoload :Adapter
2324
autoload :Null

lib/active_model_serializers/adapter/attributes.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def initialize(serializer, options = {})
88
end
99

1010
def serializable_hash(options = nil)
11-
options ||= {}
11+
options = serialization_options(options)
1212

1313
if serializer.respond_to?(:each)
1414
serializable_hash_for_collection(options)

lib/active_model_serializers/adapter/base.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ def cached_name
1919
@cached_name ||= self.class.name.demodulize.underscore
2020
end
2121

22+
# Subclasses that implement this method must first call
23+
# options = serialization_options(options)
2224
def serializable_hash(_options = nil)
2325
fail NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
2426
end
@@ -41,6 +43,10 @@ def cache_check(serializer)
4143

4244
private
4345

46+
def serialization_options(options)
47+
(options ||= {}).slice(*ActiveModel::Serializer::SERIALIZABLE_HASH_VALID_KEYS) # rubocop:disable Lint/UselessAssignment
48+
end
49+
4450
def meta
4551
instance_options.fetch(:meta, nil)
4652
end

lib/active_model_serializers/adapter/json.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module ActiveModelSerializers
22
module Adapter
33
class Json < Base
44
def serializable_hash(options = nil)
5-
options ||= {}
5+
options = serialization_options(options)
66
serialized_hash = { root => Attributes.new(serializer, instance_options).serializable_hash(options) }
77
self.class.transform_key_casing!(serialized_hash, instance_options)
88
end

test/adapter_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ def test_serializable_hash_is_abstract_method
1414
end
1515
end
1616

17+
def test_serialization_options_ensures_option_is_a_hash
18+
adapter = Class.new(ActiveModelSerializers::Adapter::Base) do
19+
def serializable_hash(options = nil)
20+
serialization_options(options)
21+
end
22+
end.new(@serializer)
23+
assert_equal({ only: [:name] }, adapter.serializable_hash(only: [:name]))
24+
assert_equal({}, adapter.serializable_hash(nil))
25+
assert_equal({}, adapter.serializable_hash({}))
26+
end
27+
1728
def test_serializer
1829
assert_equal @serializer, @adapter.serializer
1930
end

0 commit comments

Comments
 (0)