Skip to content

Commit 80eaf7e

Browse files
committed
Refactor attributes.
1 parent 390e877 commit 80eaf7e

File tree

3 files changed

+22
-16
lines changed

3 files changed

+22
-16
lines changed

lib/active_model/serializer.rb

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class Serializer
3333
self._attributes ||= []
3434
class_attribute :_attributes_keys
3535
self._attributes_keys ||= {}
36+
class_attribute :_attributes_values, instance_reader: true
37+
self._attributes_values ||= {}
3638
serializer.class_attribute :_cache
3739
serializer.class_attribute :_fragmented
3840
serializer.class_attribute :_cache_key
@@ -45,6 +47,7 @@ class Serializer
4547
def self.inherited(base)
4648
base._attributes = _attributes.dup
4749
base._attributes_keys = _attributes_keys.dup
50+
base._attributes_values = _attributes_values.dup
4851
base._cache_digest = digest_caller_file(caller.first)
4952
super
5053
end
@@ -63,18 +66,9 @@ def self.attributes(*attrs)
6366

6467
def self.attribute(attr, options = {}, &block)
6568
key = options.fetch(:key, attr)
66-
_attributes_keys[attr] = { key: key } if key != attr
67-
_attributes << key unless _attributes.include?(key)
68-
69-
ActiveModelSerializers.silence_warnings do
70-
define_method key do
71-
if block_given?
72-
instance_eval(&block)
73-
else
74-
object.read_attribute_for_serialization(attr)
75-
end
76-
end unless method_defined?(key) || _fragmented.respond_to?(attr)
77-
end
69+
_attributes_keys[attr] = { key: key }
70+
_attributes << attr unless _attributes.include?(key)
71+
_attributes_values[attr] = block if block_given?
7872
end
7973

8074
def self.fragmented(serializer)
@@ -163,14 +157,26 @@ def json_key
163157
root || object.class.model_name.to_s.underscore
164158
end
165159

160+
def attribute_value(name)
161+
if _attributes_values[name]
162+
instance_eval(&_attributes_values[name])
163+
elsif respond_to?(name) # To handle legacy method-based attr overriding
164+
warn 'Overriding attributes by defining a method on the serializer is deprecated. Please use the block syntax.'
165+
public_send(name)
166+
else
167+
object.read_attribute_for_serialization(name)
168+
end
169+
end
170+
166171
def attributes
167172
attributes = self.class._attributes.dup
168173

169174
attributes.each_with_object({}) do |name, hash|
175+
key = self.class._attributes_keys[name][:key]
170176
if self.class._fragmented
171-
hash[name] = self.class._fragmented.public_send(name)
177+
hash[key] = self.class._fragmented.attribute_value(name)
172178
else
173-
hash[name] = send(name)
179+
hash[key] = attribute_value(name)
174180
end
175181
end
176182
end

test/fixtures/poro.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def custom_options
142142
attributes :id, :name, :description, :slug
143143

144144
def slug
145-
"#{name}-#{id}"
145+
"#{object.name}-#{object.id}"
146146
end
147147

148148
belongs_to :author

test/serializers/attribute_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def setup
99
end
1010

1111
def test_attributes_definition
12-
assert_equal([:id, :title],
12+
assert_equal([:id, :name],
1313
@blog_serializer.class._attributes)
1414
end
1515

0 commit comments

Comments
 (0)