Methods
D
N
P
R
Instance Public methods
describe_property(property)
   # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
10 def describe_property(property) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
11   name = property_name(property).to_s
12   raise StandardError, "#{name} is not a valid property" unless property?(name)
13 
14   {
15     "x-rhino-attribute": {
16       name: name,
17       readableName: name.titleize,
18       readable: read_properties.include?(property),
19       creatable: create_properties.include?(property),
20       updatable: update_properties.include?(property)
21     },
22     readOnly: property_read_only?(name),
23     writeOnly: property_write_only?(name),
24     nullable: property_nullable?(name),
25     default: property_default(name)
26   }
27     .merge(property_type_and_format_with_override(property))
28     .merge(property_validations(property))
29     .compact
30 end
nested_array_options(name)
   # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
59 def nested_array_options(name)
60   ref_sym = name.to_sym
61 
62   array_options = {}
63 
64   if nested_attributes_options[ref_sym]
65     array_options[:creatable] = true
66     array_options[:updatable] = true
67     array_options[:destroyable] = nested_attributes_options[ref_sym][:allow_destroy]
68   end
69 
70   { "x-rhino-attribute-array": array_options.merge(_properties_array[ref_sym] || {}) }
71 end
property_default(name)
    # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
177 def property_default(name)
178   # FIXME: This will not handle datetime fields
179   # https://github.com/rails/rails/issues/27077 sets the default in the db
180   # but Blog.new does not set the default value like other attributes
181   # https://nubinary.atlassian.net/browse/NUB-298
182   _default_attributes[name].type_cast(_default_attributes[name].value_before_type_cast)
183 end
property_name(property)
   # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
33 def property_name(property)
34   property.is_a?(Hash) ? property.keys.first : property
35 end
property_nullable?(name)

If there is a presence validator in the model it is not nullable. if there is no optional: true on an association, rails will add a presence validator automatically Otherwise check the db for the actual column or foreign key setting Return nil instead of false for compaction

    # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
149 def property_nullable?(name)
150   # Check for presence validator
151   if validators.select { |v| v.is_a? ::ActiveRecord::Validations::PresenceValidator }.flat_map(&:attributes).include?(name.to_sym)
152     return false
153   end
154 
155   name = reflections[name].foreign_key if reflections.key?(name)
156 
157   # Check the column null setting
158   return columns_hash[name].null if columns_hash.key?(name)
159 
160   true
161 end
property_read_only?(name)

Return nil instead of false for compaction

    # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
164 def property_read_only?(name)
165   return unless read_properties.include?(name) && (create_properties.exclude?(name) && update_properties.exclude?(name))
166 
167   true
168 end
property_type_and_format(name)
    # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
 84 def property_type_and_format(name) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
 85   # Special cases
 86   return { type: :identifier } if name == identifier_property
 87   return { type: :string } if defined_enums.key?(name)
 88 
 89   # FIXME: Hack for tags for now
 90   if attribute_types.key?(name.to_s) && attribute_types[name.to_s].class.to_s == 'ActsAsTaggableOn::Taggable::TagListType'
 91     return {
 92       type: :array,
 93       items: {
 94         type: 'string'
 95       }
 96     }
 97   end
 98 
 99   # Use the attribute type if possible
100   return property_type_and_format_attr(name) if attribute_types.key?(name.to_s)
101 
102   return property_type_and_format_ref(name) if reflections.key?(name)
103 
104   # raise UnknownpropertyType
105   { type: :unknown }
106 end
property_type_and_format_attr(name)
   # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
46 def property_type_and_format_attr(name)
47   atype = attribute_types[name.to_s].type
48 
49   if %i[datetime date time].include?(atype)
50     return {
51       type: 'string',
52       format: atype
53     }
54   end
55 
56   { type: atype }
57 end
property_type_and_format_ref(name)
   # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
73 def property_type_and_format_ref(name)
74   # FIXME: The tr hack is to match how model_name in rails handles modularized classes
75   class_name = reflections[name].options[:class_name]&.underscore&.tr('/', '_') || name
76   return ref_descriptor(class_name) unless reflections[name].macro == :has_many
77 
78   {
79     type: :array,
80     items: ref_descriptor(class_name).merge(nested_array_options(name))
81   }
82 end
property_type_and_format_with_override(property)
    # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
108 def property_type_and_format_with_override(property)
109   name = property_name(property)
110 
111   tf = property_type_and_format(name)
112 
113   tf[:format] = _properties_format[property.to_sym] if _properties_format.key?(property.to_sym)
114 
115   tf
116 end
property_validations(property)
    # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
118 def property_validations(property) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
119   constraint_hash = {}
120 
121   # https://swagger.io/specification/
122 
123   validators_on(property).each do |v|
124     if v.is_a? ActiveModel::Validations::NumericalityValidator
125       constraint_hash[:minimum] = v.options[:greater_than] + 1
126       constraint_hash[:maximum] = v.options[:less_than] - 1
127     end
128 
129     if v.is_a? ::ActiveRecord::Validations::LengthValidator
130       constraint_hash[:minLength] = v.options[:minimum] || v.options[:is]
131       constraint_hash[:maxLength] = v.options[:maximum] || v.options[:is]
132     end
133 
134     constraint_hash[:pattern] = JsRegex.new(v.options[:with]).source if v.is_a? ::ActiveModel::Validations::FormatValidator
135 
136     constraint_hash[:enum] = v.options[:in] if v.is_a? ActiveModel::Validations::InclusionValidator
137   end
138 
139   constraint_hash[:enum] = defined_enums[property].keys if defined_enums.key?(property)
140 
141   constraint_hash.compact
142 end
property_write_only?(name)

Return nil instead of false for compaction

    # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
171 def property_write_only?(name)
172   return unless (create_properties.include?(name) || update_properties.include?(name)) && read_properties.exclude?(name)
173 
174   true
175 end
ref_descriptor(name)
   # File rhino/rhino/lib/rhino/resource/active_record_extension/properties_describe.rb
37 def ref_descriptor(name)
38   {
39     type: :reference,
40     anyOf: [
41       { '$ref'.to_sym => "#/components/schemas/#{name.singularize}" }
42     ]
43   }
44 end