Skip to content

Commit b51a432

Browse files
committed
Merge pull request #1370 from beauby/simplify-attributes
Simplify attributes handling.
2 parents df594c6 + ccb05f1 commit b51a432

File tree

3 files changed

+29
-46
lines changed

3 files changed

+29
-46
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Fixes:
3535
- [#1358](https://github.com/rails-api/active_model_serializers/pull/1358) Handle serializer file paths with spaces (@rwstauner, @bf4)
3636

3737
Misc:
38+
- [#1370](https://github.com/rails-api/active_model_serializers/pull/1370) Simplify attributes handling via a mixin (@beauby)
3839
- [#1233](https://github.com/rails-api/active_model_serializers/pull/1233) Top-level meta and meta_key options no longer handled at serializer level (@beauby)
3940
- [#1232](https://github.com/rails-api/active_model_serializers/pull/1232) fields option no longer handled at serializer level (@beauby)
4041
- [#1178](https://github.com/rails-api/active_model_serializers/pull/1178) env CAPTURE_STDERR=false lets devs see hard failures (@bf4)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module ActiveModel
2+
class Serializer
3+
Attribute = Struct.new(:name, :block) do
4+
def value(serializer)
5+
if block
6+
serializer.instance_eval(&block)
7+
else
8+
serializer.read_attribute_for_serialization(name)
9+
end
10+
end
11+
end
12+
end
13+
end

lib/active_model/serializer/attributes.rb

Lines changed: 15 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,32 @@
11
module ActiveModel
22
class Serializer
33
module Attributes
4-
# @api private
5-
class Attribute
6-
delegate :call, to: :reader
7-
8-
attr_reader :name, :reader
9-
10-
def initialize(name)
11-
@name = name
12-
@reader = :no_reader
13-
end
14-
15-
def self.build(name, block)
16-
if block
17-
AttributeBlock.new(name, block)
18-
else
19-
AttributeReader.new(name)
20-
end
21-
end
22-
end
23-
# @api private
24-
class AttributeReader < Attribute
25-
def initialize(name)
26-
super(name)
27-
@reader = ->(instance) { instance.read_attribute_for_serialization(name) }
28-
end
29-
end
30-
# @api private
31-
class AttributeBlock < Attribute
32-
def initialize(name, block)
33-
super(name)
34-
@reader = ->(instance) { instance.instance_eval(&block) }
35-
end
36-
end
37-
384
extend ActiveSupport::Concern
395

406
included do
417
with_options instance_writer: false, instance_reader: false do |serializer|
42-
serializer.class_attribute :_attribute_mappings # @api private : maps attribute key names to names to names of implementing methods, @see #attribute
43-
self._attribute_mappings ||= {}
8+
serializer.class_attribute :_attributes_data # @api private
9+
self._attributes_data ||= {}
4410
end
4511

12+
extend ActiveSupport::Autoload
13+
autoload :Attribute
14+
4615
# Return the +attributes+ of +object+ as presented
4716
# by the serializer.
4817
def attributes(requested_attrs = nil, reload = false)
4918
@attributes = nil if reload
50-
@attributes ||= self.class._attribute_mappings.each_with_object({}) do |(key, attribute_mapping), hash|
19+
@attributes ||= self.class._attributes_data.each_with_object({}) do |(key, attr), hash|
5120
next unless requested_attrs.nil? || requested_attrs.include?(key)
52-
hash[key] = attribute_mapping.call(self)
21+
hash[key] = attr.value(self)
5322
end
5423
end
5524
end
5625

5726
module ClassMethods
5827
def inherited(base)
5928
super
60-
base._attribute_mappings = _attribute_mappings.dup
29+
base._attributes_data = _attributes_data.dup
6130
end
6231

6332
# @example
@@ -85,25 +54,25 @@ def attributes(*attrs)
8554
# end
8655
def attribute(attr, options = {}, &block)
8756
key = options.fetch(:key, attr)
88-
_attribute_mappings[key] = Attribute.build(attr, block)
57+
_attributes_data[key] = Attribute.new(attr, block)
8958
end
9059

9160
# @api private
92-
# names of attribute methods
61+
# keys of attributes
9362
# @see Serializer::attribute
9463
def _attributes
95-
_attribute_mappings.keys
64+
_attributes_data.keys
9665
end
9766

9867
# @api private
9968
# maps attribute value to explict key name
10069
# @see Serializer::attribute
10170
# @see Adapter::FragmentCache#fragment_serializer
10271
def _attributes_keys
103-
_attribute_mappings
104-
.each_with_object({}) do |(key, attribute_mapping), hash|
105-
next if key == attribute_mapping.name
106-
hash[attribute_mapping.name] = { key: key }
72+
_attributes_data
73+
.each_with_object({}) do |(key, attr), hash|
74+
next if key == attr.name
75+
hash[attr.name] = { key: key }
10776
end
10877
end
10978
end

0 commit comments

Comments
 (0)