Class: Reynard::Model
- Inherits:
-
BasicObject
- Extended by:
- Forwardable
- Defined in:
- lib/reynard/model.rb
Overview
Superclass for dynamic classes generated by the object builder.
Direct Known Subclasses
Server
Class Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(attributes) ⇒ Model
Returns a new instance of Model.
16
17
18
19
20
21
22
23
24
25
26
27
|
# File 'lib/reynard/model.rb', line 16
def initialize(attributes)
if attributes.respond_to?(:each) && attributes.respond_to?(:keys)
@attributes = {}
@snake_cases = self.class.snake_cases(attributes.keys)
self.attributes = attributes
else
::Kernel.raise(
::ArgumentError,
self.class.attributes_error_message(attributes)
)
end
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(attribute_name) ⇒ Object
Until we can set accessors based on the schema
46
47
48
49
50
51
52
53
54
55
56
57
|
# File 'lib/reynard/model.rb', line 46
def method_missing(attribute_name, *)
return false unless @attributes
attribute_name = attribute_name.to_s
if @attributes.key?(attribute_name)
@attributes[attribute_name]
else
@attributes.fetch(@snake_cases.fetch(attribute_name))
end
rescue ::KeyError
::Kernel.raise ::NoMethodError, "undefined method `#{attribute_name}' for #{inspect}"
end
|
Class Attribute Details
.inflector ⇒ Object
82
83
84
|
# File 'lib/reynard/model.rb', line 82
def self.inflector
@inflector ||= ::Reynard::Inflector.new
end
|
.schema ⇒ Object
Holds references to the full schema for the model if available.
11
12
13
|
# File 'lib/reynard/model.rb', line 11
def schema
@schema
end
|
Class Method Details
.attributes_error_message(attributes) ⇒ Object
95
96
97
98
99
|
# File 'lib/reynard/model.rb', line 95
def self.attributes_error_message(attributes)
'Models must be intialized with an enumerable object that behaves like a Hash, got: ' \
"`#{attributes.inspect}'. Usually this means the schema defined in the OpenAPI " \
"specification doesn't fit the payload in the HTTP response."
end
|
.cast(name, value) ⇒ Object
72
73
74
75
76
77
78
79
80
|
# File 'lib/reynard/model.rb', line 72
def self.cast(name, value)
return if value.nil?
return value unless schema
property = schema.property_schema(name)
return value unless property
::Reynard::ObjectBuilder.new(schema: property, inflector:, parsed_body: value).call
end
|
.snake_cases(property_names) ⇒ Object
86
87
88
89
90
91
92
93
|
# File 'lib/reynard/model.rb', line 86
def self.snake_cases(property_names)
property_names.each_with_object({}) do |property_name, snake_cases|
snake_case = inflector.snake_case(property_name)
next if snake_case == property_name
snake_cases[snake_case] = property_name
end
end
|
Instance Method Details
#attributes=(attributes) ⇒ Object
39
40
41
42
43
|
# File 'lib/reynard/model.rb', line 39
def attributes=(attributes)
attributes.each do |name, value|
@attributes[name.to_s] = self.class.cast(name, value)
end
end
|
#inspect ⇒ Object
35
36
37
|
# File 'lib/reynard/model.rb', line 35
def inspect
"#<#{self.class.name}:0x#{object_id.to_s(16)}>"
end
|
#respond_to_missing?(attribute_name) ⇒ Boolean
59
60
61
62
63
64
65
66
|
# File 'lib/reynard/model.rb', line 59
def respond_to_missing?(attribute_name, *)
attribute_name = attribute_name.to_s
return true if @attributes.key?(attribute_name)
@snake_cases.key?(attribute_name) && @attributes.key?(@snake_cases[attribute_name])
rescue ::NameError
false
end
|
#try(attribute_name) ⇒ Object
68
69
70
|
# File 'lib/reynard/model.rb', line 68
def try(attribute_name)
respond_to_missing?(attribute_name) ? send(attribute_name) : nil
end
|