Skip to content

Commit b8f54ae

Browse files
committed
add if/unless options to attribute
1 parent da7e6dc commit b8f54ae

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

lib/active_model/serializer.rb

Lines changed: 40 additions & 2 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_conditions
37+
self._attributes_conditions ||= {}
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_conditions = _attributes_conditions.dup
4851
base._cache_digest = digest_caller_file(caller.first)
4952
super
5053
end
@@ -54,10 +57,11 @@ def self.type(type)
5457
end
5558

5659
def self.attributes(*attrs)
60+
options = attrs.last.class == Hash ? attrs.pop : {}
5761
attrs = attrs.first if attrs.first.class == Array
5862

5963
attrs.each do |attr|
60-
attribute(attr)
64+
attribute(attr, options)
6165
end
6266
end
6367

@@ -66,6 +70,17 @@ def self.attribute(attr, options = {})
6670
_attributes_keys[attr] = { key: key } if key != attr
6771
_attributes << key unless _attributes.include?(key)
6872

73+
[:if, :unless].each do |switch|
74+
next unless options.key?(switch)
75+
condition = { switch => options[switch] }
76+
77+
if _attributes_conditions[condition]
78+
_attributes_conditions[condition] << key
79+
else
80+
_attributes_conditions[condition] = [key]
81+
end
82+
end
83+
6984
ActiveModelSerializers.silence_warnings do
7085
define_method key do
7186
object.read_attribute_for_serialization(attr)
@@ -160,7 +175,7 @@ def json_key
160175
end
161176

162177
def attributes
163-
attributes = self.class._attributes.dup
178+
attributes = self.class._attributes.dup - useless_attributes_keys
164179

165180
attributes.each_with_object({}) do |name, hash|
166181
if self.class._fragmented
@@ -171,8 +186,31 @@ def attributes
171186
end
172187
end
173188

189+
def useless_attributes_keys
190+
self.class
191+
._attributes_conditions
192+
.dup
193+
.each_with_object([]) do |(switch_hash, keys), useless_keys|
194+
case switch_hash.keys
195+
when [:if]
196+
useless_keys << keys unless judge_attribute(switch_hash[:if])
197+
when [:unless]
198+
useless_keys << keys if judge_attribute(switch_hash[:unless])
199+
else
200+
useless_keys
201+
end
202+
end.flatten
203+
end
204+
174205
protected
175206

176207
attr_accessor :instance_options
208+
209+
private
210+
211+
def judge_attribute(condition)
212+
(condition.is_a?(Symbol) && send(condition)) ||
213+
(condition.respond_to?(:call) && condition.call)
214+
end
177215
end
178216
end

test/serializers/attribute_test.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,22 @@ def id
7171

7272
assert_equal('custom', hash[:blog][:id])
7373
end
74+
75+
def test_attributes_conditions
76+
serializer_class = Class.new(ActiveModel::Serializer) do
77+
attribute :id
78+
attributes :name, :title, if: :admin?
79+
attribute :type, unless: proc { true }
80+
81+
def admin?
82+
false
83+
end
84+
end
85+
serializer = serializer_class.new(@blog)
86+
87+
assert_equal([:name, :title, :type], serializer.useless_attributes_keys)
88+
assert_equal({ id: 1 }, serializer.attributes)
89+
end
7490
end
7591
end
7692
end

0 commit comments

Comments
 (0)