lib/active_model/serializer/field.rb
# frozen_string_literal: true
module ActiveModel
class Serializer
# Holds all the meta-data about a field (i.e. attribute or association) as it was
# 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
#
# @api private
#
def value(serializer)
if block
serializer.instance_eval(&block)
else
serializer.read_attribute_for_serialization(name)
end
end
# Decide whether the field should be serialized by the given serializer instance.
# @param [Serializer] The serializer instance
# @return [Bool]
#
# @api private
#
def excluded?(serializer)
case condition_type
when :if
!evaluate_condition(serializer)
when :unless
evaluate_condition(serializer)
else
false
end
end
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)
:if
elsif options.key?(:unless)
:unless
else
:none
end
end
def condition
options[condition_type]
end
end
end
end