File: required_validator.rb

package info (click to toggle)
ruby-graphql 2.2.17-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,584 kB
  • sloc: ruby: 67,505; ansic: 1,753; yacc: 831; javascript: 331; makefile: 6
file content (82 lines) | stat: -rw-r--r-- 2,990 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
# frozen_string_literal: true

module GraphQL
  class Schema
    class Validator
      # Use this validator to require _one_ of the named arguments to be present.
      # Or, use Arrays of symbols to name a valid _set_ of arguments.
      #
      # (This is for specifying mutually exclusive sets of arguments.)
      #
      # @example Require exactly one of these arguments
      #
      #   field :update_amount, IngredientAmount, null: false do
      #     argument :ingredient_id, ID, required: true
      #     argument :cups, Integer, required: false
      #     argument :tablespoons, Integer, required: false
      #     argument :teaspoons, Integer, required: false
      #     validates required: { one_of: [:cups, :tablespoons, :teaspoons] }
      #   end
      #
      # @example Require one of these _sets_ of arguments
      #
      #  field :find_object, Node, null: true do
      #    argument :node_id, ID, required: false
      #    argument :object_type, String, required: false
      #    argument :object_id, Integer, required: false
      #    # either a global `node_id` or an `object_type`/`object_id` pair is required:
      #    validates required: { one_of: [:node_id, [:object_type, :object_id]] }
      #  end
      #
      # @example require _some_ value for an argument, even if it's null
      #   field :update_settings, AccountSettings do
      #     # `required: :nullable` means this argument must be given, but may be `null`
      #     argument :age, Integer, required: :nullable
      #   end
      #
      class RequiredValidator < Validator
        # @param one_of [Symbol, Array<Symbol>] An argument, or a list of arguments, that represents a valid set of inputs for this field
        # @param message [String]
        def initialize(one_of: nil, argument: nil, message: "%{validated} has the wrong arguments", **default_options)
          @one_of = if one_of
            one_of
          elsif argument
            [argument]
          else
            raise ArgumentError, "`one_of:` or `argument:` must be given in `validates required: {...}`"
          end
          @message = message
          super(**default_options)
        end

        def validate(_object, _context, value)
          matched_conditions = 0

          if !value.nil?
            @one_of.each do |one_of_condition|
              case one_of_condition
              when Symbol
                if value.key?(one_of_condition)
                  matched_conditions += 1
                end
              when Array
                if one_of_condition.all? { |k| value.key?(k) }
                  matched_conditions += 1
                  break
                end
              else
                raise ArgumentError, "Unknown one_of condition: #{one_of_condition.inspect}"
              end
            end
          end

          if matched_conditions == 1
            nil # OK
          else
            @message
          end
        end
      end
    end
  end
end