diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index d5bd0028..bb0170a5 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -79,10 +79,12 @@ end end def attributes(*attrs) - @_attributes.concat attrs - attrs.each do |attr| - define_method attr do + striped_attr = strip_attribute attr + + @_attributes << striped_attr + + define_method striped_attr do object.read_attribute_for_serialization attr end unless method_defined?(attr) end @@ -98,6 +100,14 @@ end private + def strip_attribute(attr) + symbolized = attr.is_a?(Symbol) + + attr = attr.to_s.gsub(/\?\Z/, '') + attr = attr.to_sym if symbolized + attr + end + def build_serializer_class(resource, options) "".tap do |klass_name| klass_name << "#{options[:namespace]}::" if options[:namespace] diff --git a/test/fixtures/poro.rb b/test/fixtures/poro.rb index 8b4f6c35..fae44cb3 100644 --- a/test/fixtures/poro.rb +++ b/test/fixtures/poro.rb @@ -1,11 +1,13 @@ class Model - def initialize(hash={}) + def initialize(hash = {}) @attributes = hash end def read_attribute_for_serialization(name) if name == :id || name == 'id' object_id + elsif respond_to?(name) + send name else @attributes[name] end diff --git a/test/unit/active_model/serializer/attributes_test.rb b/test/unit/active_model/serializer/attributes_test.rb index 5187cc55..17822843 100644 --- a/test/unit/active_model/serializer/attributes_test.rb +++ b/test/unit/active_model/serializer/attributes_test.rb @@ -36,6 +36,22 @@ module ActiveModel assert_equal([:name, :description], another_inherited_serializer_klass._attributes) end + + def tests_query_attributes_strip_question_mark + model = Class.new(::Model) do + def strip? + true + end + end + + serializer = Class.new(ActiveModel::Serializer) do + attributes :strip? + end + + actual = serializer.new(model.new).as_json + + assert_equal({ strip: true }, actual) + end end end end