Class: Esquema::Property

Inherits:
Object
  • Object
show all
Defined in:
lib/esquema/property.rb

Overview

Represents a property in the Esquema schema.

Constant Summary collapse

DB_TO_JSON_TYPE_MAPPINGS =

Mapping of database types to JSON types.

{
  date: "date",
  datetime: "date-time",
  time: "time",
  string: "string",
  text: "string",
  integer: "integer",
  float: "number",
  number: "number",
  decimal: "number",
  boolean: "boolean",
  array: "array",
  object: "object"
}.freeze
NUMERIC_CONSTRAINT_KEYWORDS =
%i[minimum maximum exclusiveMinimum exclusiveMaximum multipleOf].freeze
STRING_CONSTRAINT_KEYWORDS =
%i[maxLength minLength pattern format].freeze
ARRAY_CONSTRAINT_KEYWORDS =
%i[maxItems minItems uniqueItems items].freeze
OBJECT_CONSTRAINT_KEYWORDS =
%i[maxProperties minProperties properties additionalProperties dependencies].freeze
LOGICAL_KEYWORDS =
%i[allOf anyOf oneOf not].freeze
GENERIC_KEYWORDS =
%i[type default title description enum const].freeze
KEYWORDS =
(
  NUMERIC_CONSTRAINT_KEYWORDS +
  STRING_CONSTRAINT_KEYWORDS  +
  ARRAY_CONSTRAINT_KEYWORDS   +
  OBJECT_CONSTRAINT_KEYWORDS  +
  LOGICAL_KEYWORDS            +
  GENERIC_KEYWORDS
).freeze
FORMAT_OPTIONS =
%i[date-time date time email hostname ipv4 ipv6 uri uuid uri-reference uri-template].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(object, options = {}) ⇒ Property

Initializes a new Property instance.

An object can be any of the following instance types:

An ActiveRecord column. Example: ActiveRecord::ConnectionAdapters::SQLite3::Column
An ActiveRecord association reflection. Example: ActiveRecord::Reflection::BelongsToReflection
An Esquema virtual column. Example: Esquema::VirtualColumn

Parameters:

  • object (Object)

    The object to build the property for.

  • options (Hash) (defaults to: {})

    Additional options for the property.

Raises:

  • (ArgumentError)

    If the property does not have a name.



52
53
54
55
56
57
# File 'lib/esquema/property.rb', line 52

def initialize(object, options = {})
  raise ArgumentError, "property must have a name" unless object.respond_to?(:name)

  @object = object
  @options = options
end

Instance Attribute Details

#objectObject (readonly)

Returns the value of attribute object.



41
42
43
# File 'lib/esquema/property.rb', line 41

def object
  @object
end

#optionsObject (readonly)

Returns the value of attribute options.



41
42
43
# File 'lib/esquema/property.rb', line 41

def options
  @options
end

Instance Method Details

#as_jsonHash

Converts the Property instance to a JSON representation.

Returns:

  • (Hash)

    The JSON representation of the Property.



62
63
64
65
66
67
68
69
# File 'lib/esquema/property.rb', line 62

def as_json
  KEYWORDS.each_with_object({}) do |property, hash|
    value = send("build_#{property.downcase}")
    next if value.nil? || (value.is_a?(String) && value.empty?)

    hash[property] = value
  end.compact
end

#build_additionalpropertiesObject



210
211
212
# File 'lib/esquema/property.rb', line 210

def build_additionalproperties
  options[:additionalProperties]
end

#build_allofObject



218
219
220
# File 'lib/esquema/property.rb', line 218

def build_allof
  options[:allOf]
end

#build_anyofObject



222
223
224
# File 'lib/esquema/property.rb', line 222

def build_anyof
  options[:anyOf]
end

#build_constObject



234
235
236
# File 'lib/esquema/property.rb', line 234

def build_const
  options[:const]
end

#build_defaultObject?

Builds the default attribute for the Property.

Returns:

  • (Object, nil)

    The default attribute.



81
82
83
84
85
86
87
# File 'lib/esquema/property.rb', line 81

def build_default
  return unless object.respond_to?(:default)

  default_value = object.default || options[:default].presence

  @default = TypeCaster.cast(object.type, default_value) unless default_value.nil?
end

#build_dependenciesObject



214
215
216
# File 'lib/esquema/property.rb', line 214

def build_dependencies
  options[:dependencies]
end

#build_descriptionString?

Builds the description attribute for the Property.

Returns:

  • (String, nil)

    The description attribute.



103
104
105
# File 'lib/esquema/property.rb', line 103

def build_description
  options[:description]
end

#build_enumArray?

Builds the enum attribute for the Property.

Returns:

  • (Array, nil)

    The enum attribute.



124
125
126
# File 'lib/esquema/property.rb', line 124

def build_enum
  options[:enum]
end

#build_exclusivemaximumObject



140
141
142
# File 'lib/esquema/property.rb', line 140

def build_exclusivemaximum
  options[:exclusiveMaximum]
end

#build_exclusiveminimumObject



136
137
138
# File 'lib/esquema/property.rb', line 136

def build_exclusiveminimum
  options[:exclusiveMinimum]
end

#build_formatObject



160
161
162
# File 'lib/esquema/property.rb', line 160

def build_format
  options[:format]
end

#build_itemsHash?

Builds the items attribute for the Property.

Returns:

  • (Hash, nil)

    The items attribute.



110
111
112
113
114
115
116
117
118
119
# File 'lib/esquema/property.rb', line 110

def build_items
  return unless object.try(:collection?)

  case object.type
  when :array
    { type: DB_TO_JSON_TYPE_MAPPINGS[object.item_type] }
  else
    Builder.new(object.klass).build_schema
  end
end

#build_maximumObject



132
133
134
# File 'lib/esquema/property.rb', line 132

def build_maximum
  options[:maximum]
end

#build_maxitemsObject

rubocop:disable Metrics/AbcSize

Raises:

  • (ArgumentError)


164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/esquema/property.rb', line 164

def build_maxitems # rubocop:disable Metrics/AbcSize
  raise ArgumentError, "maxItems must be an integer" if options[:maxItems] && !options[:maxItems].is_a?(Integer)

  if options[:maxItems]&.negative?
    raise ArgumentError,
          "maxItems must be a non-negative integer"
  end

  if options[:maxItems] && options[:type] != :array
    raise ArgumentError, "maxItems must be use for array type properties only."
  end

  options[:maxItems]
end

#build_maxlengthObject



148
149
150
# File 'lib/esquema/property.rb', line 148

def build_maxlength
  options[:maxLength]
end

#build_maxpropertiesObject



202
203
204
# File 'lib/esquema/property.rb', line 202

def build_maxproperties
  options[:maxProperties]
end

#build_minimumObject



128
129
130
# File 'lib/esquema/property.rb', line 128

def build_minimum
  options[:minimum]
end

#build_minitemsObject

rubocop:disable Metrics/AbcSize

Raises:

  • (ArgumentError)


179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/esquema/property.rb', line 179

def build_minitems # rubocop:disable Metrics/AbcSize
  raise ArgumentError, "minItems must be an integer" if options[:minItems] && !options[:minItems].is_a?(Integer)

  if options[:minItems]&.negative?
    raise ArgumentError,
          "minItems must be a non-negative integer"
  end

  if options[:minItems] && options[:type] != :array
    raise ArgumentError, "minItems must be use for array type properties only."
  end

  options[:minItems]
end

#build_minlengthObject



152
153
154
# File 'lib/esquema/property.rb', line 152

def build_minlength
  options[:minLength]
end

#build_minpropertiesObject



206
207
208
# File 'lib/esquema/property.rb', line 206

def build_minproperties
  options[:minProperties]
end

#build_multipleofObject



144
145
146
# File 'lib/esquema/property.rb', line 144

def build_multipleof
  options[:multipleof]
end

#build_notObject



230
231
232
# File 'lib/esquema/property.rb', line 230

def build_not
  options[:not]
end

#build_oneofObject



226
227
228
# File 'lib/esquema/property.rb', line 226

def build_oneof
  options[:oneOf]
end

#build_patternObject



156
157
158
# File 'lib/esquema/property.rb', line 156

def build_pattern
  options[:pattern]
end

#build_propertiesObject



198
199
200
# File 'lib/esquema/property.rb', line 198

def build_properties
  options[:properties]
end

#build_titleString

Builds the title attribute for the Property.

Returns:

  • (String)

    The title attribute.



74
75
76
# File 'lib/esquema/property.rb', line 74

def build_title
  options[:title].presence || object.name.to_s.humanize
end

#build_typeString?

Builds the type attribute for the Property.

Returns:

  • (String, nil)

    The type attribute.



92
93
94
95
96
97
98
# File 'lib/esquema/property.rb', line 92

def build_type
  return DB_TO_JSON_TYPE_MAPPINGS[:array] if object.try(:collection?)

  return unless object.respond_to?(:type)

  @type = DB_TO_JSON_TYPE_MAPPINGS[object.type]
end

#build_uniqueitemsObject



194
195
196
# File 'lib/esquema/property.rb', line 194

def build_uniqueitems
  options[:uniqueItems]
end