Module: WCC::Contentful::ModelValidators

Included in:
Model
Defined in:
lib/wcc/contentful/model_validators.rb,
lib/wcc/contentful/model_validators/dsl.rb

Defined Under Namespace

Classes: FieldDsl, ProcDsl

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.transform_content_types_for_validation(content_types) ⇒ Object

Accepts a content types response from the API and transforms it to be acceptible for the validator.



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/wcc/contentful/model_validators.rb', line 105

def self.transform_content_types_for_validation(content_types)
  if !content_types.is_a?(Array) && items = content_types.try(:[], 'items')
    content_types = items
  end

  # Transform the array into a hash keyed by content type ID
  content_types.each_with_object({}) do |ct, ct_hash|
    # Transform the fields into a hash keyed by field ID
    ct['fields'] =
      ct['fields'].each_with_object({}) do |f, f_hash|
        f_hash[f['id']] = f
      end

    ct_hash[ct.dig('sys', 'id')] = ct
  end
end

Instance Method Details

#no_validate_field(field) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/wcc/contentful/model_validators.rb', line 95

def no_validate_field(field)
  ct = try(:content_type) || name.demodulize.camelize(:lower)
  return unless v = validations[ct]

  field = field.to_s.camelize(:lower) unless field.is_a?(String)
  v.reject! { |dsl| dsl.try(:field) == field }
end

#schemaObject



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
# File 'lib/wcc/contentful/model_validators.rb', line 8

def schema
  return if validations.nil? || validations.empty?

  all_field_validations =
    validations.each_with_object({}) do |(content_type, procs), h|
      next if procs.empty?

      # "page": {
      #   "sys": { ... }
      #   "fields": {
      #     "title": { ... },
      #     "sections": { ... },
      #     ...
      #   }
      # }
      h[content_type] =
        Dry::Validation.Schema do
          # Had to dig through the internals of Dry::Validation to find
          # this magic incantation
          procs.each { |dsl| instance_eval(&dsl.to_proc) }
        end
    end

  Dry::Validation.Schema do
    all_field_validations.each do |content_type, fields_schema|
      required(content_type).schema do
        required('fields').schema(fields_schema)
      end
    end
  end
end

#validate_field(field, type, *options) ⇒ Object

Validates a single field is of the expected type. Type expectations are one of:

:String

the field type must be ‘Symbol` or `Text`

:Int

the field type must be ‘Integer`

:Float

the field type must be ‘Number`

:DateTime

the field type must be ‘Date’

:Asset

the field must be a link and the ‘linkType` must be `Asset`

:Link

the field must be a link and the ‘linkType` must be `Entry`.

:Location

the field type must be ‘Location`

:Boolean

the field type must be ‘Boolean`

:Json

the field type must be ‘Json` - a json blob.

:Array

the field must be a List.

Additional validation options can be enforced:

:required

the ‘Required Field’ checkbox must be checked

:optional

the ‘Required Field’ checkbox must not be checked

:link_to

(only ‘:Link` or `:Array` type) the given content type(s) must be checked in the ’Accept only specified entry type’ validations Example:

validate_field :button, :Link, link_to: ['button', 'altButton']
:items

(only ‘:Array` type) the items of the list must be of the given type. Example:

validate_field :my_strings, :Array, items: :String

Examples: see WCC::Contentful::Model::Menu and WCC::Contentful::Model::MenuButton



88
89
90
91
92
93
# File 'lib/wcc/contentful/model_validators.rb', line 88

def validate_field(field, type, *options)
  dsl = FieldDsl.new(field, type, options)

  ct = try(:content_type) || name.demodulize.camelize(:lower)
  (validations[ct] ||= []) << dsl
end

#validate_fields(&block) ⇒ Object

Accepts a block which uses the dry-validation DSL to validate the ‘fields’ object of a content type.

Raises:

  • (ArgumentError)


50
51
52
53
54
55
56
57
# File 'lib/wcc/contentful/model_validators.rb', line 50

def validate_fields(&block)
  raise ArgumentError, 'validate_fields requires a block' unless block_given?

  dsl = ProcDsl.new(Proc.new(&block))

  ct = try(:content_type) || name.demodulize.camelize(:lower)
  (validations[ct] ||= []) << dsl
end

#validationsObject



40
41
42
43
44
45
46
# File 'lib/wcc/contentful/model_validators.rb', line 40

def validations
  # This needs to be a class variable so that subclasses defined in application
  # code can add to the total package of model validations
  # rubocop:disable Style/ClassVars
  @@validations ||= {}
  # rubocop:enable Style/ClassVars
end