File: field.rb

package info (click to toggle)
ruby-active-model-serializers 0.10.12-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,752 kB
  • sloc: ruby: 13,138; sh: 53; makefile: 6
file content (92 lines) | stat: -rw-r--r-- 2,285 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# 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