Skip to content

Commit 97ac16b

Browse files
committed
String/Lambda support for conditional attributes/associations
1 parent f0fa743 commit 97ac16b

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

lib/active_model/serializer/field.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,29 @@ def value(serializer)
2727
def excluded?(serializer)
2828
case condition_type
2929
when :if
30-
!serializer.public_send(condition)
30+
!condition_lambda.call(serializer)
3131
when :unless
32-
serializer.public_send(condition)
32+
condition_lambda.call(serializer)
3333
else
3434
false
3535
end
3636
end
3737

3838
private
3939

40+
def condition_lambda
41+
case condition
42+
when Symbol
43+
-> (serializer) { serializer.public_send(condition) }
44+
when String
45+
-> (serializer) { serializer.instance_eval(condition) }
46+
when Proc
47+
-> (serializer) { condition.call(serializer) }
48+
else
49+
raise ArgumentError
50+
end
51+
end
52+
4053
def condition_type
4154
@condition_type ||=
4255
if options.key?(:if)

test/serializers/associations_test.rb

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def test_associations_namespaced_resources
239239
end
240240
end
241241

242-
def test_conditional_associations
242+
def test_symbol_conditional_associations
243243
serializer = Class.new(ActiveModel::Serializer) do
244244
belongs_to :if_assoc_included, if: :true
245245
belongs_to :if_assoc_excluded, if: :false
@@ -261,6 +261,36 @@ def false
261261

262262
assert_equal(expected, hash)
263263
end
264+
265+
def test_string_conditional_associations
266+
serializer = Class.new(ActiveModel::Serializer) do
267+
belongs_to :if_assoc_included, if: 'object.true'
268+
belongs_to :if_assoc_excluded, if: 'object.false'
269+
belongs_to :unless_assoc_included, unless: 'object.false'
270+
belongs_to :unless_assoc_excluded, unless: 'object.true'
271+
end
272+
273+
model = ::Model.new(true: true, false: false)
274+
hash = serializable(model, serializer: serializer).serializable_hash
275+
expected = { if_assoc_included: nil, unless_assoc_included: nil }
276+
277+
assert_equal(expected, hash)
278+
end
279+
280+
def test_lambda_conditional_associations
281+
serializer = Class.new(ActiveModel::Serializer) do
282+
belongs_to :if_assoc_included, if: -> (s) { s.object.true }
283+
belongs_to :if_assoc_excluded, if: -> (s) { s.object.false }
284+
belongs_to :unless_assoc_included, unless: -> (s) { s.object.false }
285+
belongs_to :unless_assoc_excluded, unless: -> (s) { s.object.true }
286+
end
287+
288+
model = ::Model.new(true: true, false: false)
289+
hash = serializable(model, serializer: serializer).serializable_hash
290+
expected = { if_assoc_included: nil, unless_assoc_included: nil }
291+
292+
assert_equal(expected, hash)
293+
end
264294
end
265295
end
266296
end

test/serializers/attribute_test.rb

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def test_virtual_attribute_block
9696
assert_equal(expected, hash)
9797
end
9898

99-
def test_conditional_attributes
99+
def test_symbol_conditional_attributes
100100
serializer = Class.new(ActiveModel::Serializer) do
101101
attribute :if_attribute_included, if: :true
102102
attribute :if_attribute_excluded, if: :false
@@ -118,6 +118,36 @@ def false
118118

119119
assert_equal(expected, hash)
120120
end
121+
122+
def test_string_conditional_attributes
123+
serializer = Class.new(ActiveModel::Serializer) do
124+
attribute :if_attribute_included, if: 'object.true'
125+
attribute :if_attribute_excluded, if: 'object.false'
126+
attribute :unless_attribute_included, unless: 'object.false'
127+
attribute :unless_attribute_excluded, unless: 'object.true'
128+
end
129+
130+
model = ::Model.new(true: true, false: false)
131+
hash = serializable(model, serializer: serializer).serializable_hash
132+
expected = { if_attribute_included: nil, unless_attribute_included: nil }
133+
134+
assert_equal(expected, hash)
135+
end
136+
137+
def test_lambda_conditional_attributes
138+
serializer = Class.new(ActiveModel::Serializer) do
139+
attribute :if_attribute_included, if: -> (s) { s.object.true }
140+
attribute :if_attribute_excluded, if: -> (s) { s.object.false }
141+
attribute :unless_attribute_included, unless: -> (s) { s.object.false }
142+
attribute :unless_attribute_excluded, unless: -> (s) { s.object.true }
143+
end
144+
145+
model = ::Model.new(true: true, false: false)
146+
hash = serializable(model, serializer: serializer).serializable_hash
147+
expected = { if_attribute_included: nil, unless_attribute_included: nil }
148+
149+
assert_equal(expected, hash)
150+
end
121151
end
122152
end
123153
end

0 commit comments

Comments
 (0)