String/Lambda support for conditional attributes/associations

This commit is contained in:
Fumiaki MATSUSHIMA
2016-04-21 22:30:49 +09:00
parent d43b32a4d3
commit aa087a22b5
5 changed files with 126 additions and 31 deletions

View File

@@ -4,6 +4,12 @@ module ActiveModel
# specified in the ActiveModel::Serializer class.
# Notice that the field block is evaluated in the context of the serializer.
Field = Struct.new(:name, :options, :block) do
def initialize(*)
super
validate_condition!
end
# Compute the actual value of a field for a given serializer instance.
# @param [Serializer] The serializer instance for which the value is computed.
# @return [Object] value
@@ -27,9 +33,9 @@ module ActiveModel
def excluded?(serializer)
case condition_type
when :if
!serializer.public_send(condition)
!evaluate_condition(serializer)
when :unless
serializer.public_send(condition)
evaluate_condition(serializer)
else
false
end
@@ -37,6 +43,34 @@ module ActiveModel
private
def validate_condition!
return if condition_type == :none
case condition
when Symbol, String, Proc
# noop
else
fail TypeError, "#{condition_type.inspect} should be a Symbol, String or Proc"
end
end
def evaluate_condition(serializer)
case condition
when Symbol
serializer.public_send(condition)
when String
serializer.instance_eval(condition)
when Proc
if condition.arity.zero?
serializer.instance_exec(&condition)
else
serializer.instance_exec(serializer, &condition)
end
else
nil
end
end
def condition_type
@condition_type ||=
if options.key?(:if)