33require 'active_model/serializer/array_serializer'
44require 'active_model/serializer/include_tree'
55require 'active_model/serializer/associations'
6+ require 'active_model/serializer/attributes'
67require 'active_model/serializer/configuration'
78require 'active_model/serializer/fieldset'
89require 'active_model/serializer/lint'
@@ -13,6 +14,7 @@ module ActiveModel
1314 class Serializer
1415 include Configuration
1516 include Associations
17+ include Attributes
1618 require 'active_model/serializer/adapter'
1719
1820 # Matches
@@ -45,14 +47,9 @@ def self.digest_caller_file(caller_line)
4547 end
4648
4749 with_options instance_writer : false , instance_reader : false do |serializer |
48- class_attribute :_type , instance_reader : true
49- class_attribute :_attributes # @api private : names of attribute methods, @see Serializer#attribute
50- self . _attributes ||= [ ]
51- class_attribute :_attributes_keys # @api private : maps attribute value to explict key name, @see Serializer#attribute
52- self . _attributes_keys ||= { }
53- class_attribute :_links # @api private : links definitions, @see Serializer#link
50+ serializer . class_attribute :_type , instance_reader : true
51+ serializer . class_attribute :_links # @api private : links definitions, @see Serializer#link
5452 self . _links ||= { }
55-
5653 serializer . class_attribute :_cache # @api private : the cache object
5754 serializer . class_attribute :_fragmented # @api private : @see ::fragmented
5855 serializer . class_attribute :_cache_key # @api private : when present, is first item in cache_key
@@ -69,12 +66,10 @@ def self.digest_caller_file(caller_line)
6966 serializer . class_attribute :_cache_digest # @api private : Generated
7067 end
7168
72- # Serializers inherit _attributes and _attributes_keys .
69+ # Serializers inherit _attribute_mappings, _reflections, and _links .
7370 # Generates a unique digest for each serializer at load.
7471 def self . inherited ( base )
7572 caller_line = caller . first
76- base . _attributes = _attributes . dup
77- base . _attributes_keys = _attributes_keys . dup
7873 base . _links = _links . dup
7974 base . _cache_digest = digest_caller_file ( caller_line )
8075 super
@@ -91,37 +86,6 @@ def self.link(name, value = nil, &block)
9186 _links [ name ] = block || value
9287 end
9388
94- # @example
95- # class AdminAuthorSerializer < ActiveModel::Serializer
96- # attributes :id, :name, :recent_edits
97- def self . attributes ( *attrs )
98- attrs = attrs . first if attrs . first . class == Array
99-
100- attrs . each do |attr |
101- attribute ( attr )
102- end
103- end
104-
105- # @example
106- # class AdminAuthorSerializer < ActiveModel::Serializer
107- # attributes :id, :recent_edits
108- # attribute :name, key: :title
109- #
110- # def recent_edits
111- # object.edits.last(5)
112- # enr
113- def self . attribute ( attr , options = { } )
114- key = options . fetch ( :key , attr )
115- _attributes_keys [ attr ] = { key : key } if key != attr
116- _attributes << key unless _attributes . include? ( key )
117-
118- ActiveModelSerializers . silence_warnings do
119- define_method key do
120- object . read_attribute_for_serialization ( attr )
121- end unless method_defined? ( key ) || _fragmented . respond_to? ( attr )
122- end
123- end
124-
12589 # @api private
12690 # Used by FragmentCache on the CachedSerializer
12791 # to call attribute methods on the fragmented cached serializer.
@@ -220,6 +184,15 @@ def self.get_serializer_for(klass)
220184 end
221185 end
222186
187+ def self . _serializer_instance_method_defined? ( name )
188+ _serializer_instance_methods . include? ( name )
189+ end
190+
191+ def self . _serializer_instance_methods
192+ @_serializer_instance_methods ||= ( public_instance_methods - Object . public_instance_methods ) . to_set
193+ end
194+ private_class_method :_serializer_instance_methods
195+
223196 attr_accessor :object , :root , :scope
224197
225198 # `scope_name` is set as :current_user by default in the controller.
@@ -244,16 +217,13 @@ def json_key
244217 root || object . class . model_name . to_s . underscore
245218 end
246219
247- # Return the +attributes+ of +object+ as presented
248- # by the serializer.
249- def attributes ( requested_attrs = nil )
250- self . class . _attributes . each_with_object ( { } ) do |name , hash |
251- next unless requested_attrs . nil? || requested_attrs . include? ( name )
252- if self . class . _fragmented
253- hash [ name ] = self . class . _fragmented . public_send ( name )
254- else
255- hash [ name ] = send ( name )
256- end
220+ def read_attribute_for_serialization ( attr )
221+ if self . class . _serializer_instance_method_defined? ( attr )
222+ send ( attr )
223+ elsif self . class . _fragmented
224+ self . class . _fragmented . read_attribute_for_serialization ( attr )
225+ else
226+ object . read_attribute_for_serialization ( attr )
257227 end
258228 end
259229
0 commit comments