Class: Showroom::Resource
- Inherits:
-
Object
- Object
- Showroom::Resource
- Defined in:
- lib/showroom/models/resource.rb
Overview
Base class for all Showroom model objects.
Wraps a plain Hash, providing dot-notation attribute access, association DSL macros (Resource.has_many / Resource.has_one), deep serialization via #to_h, and a configurable #inspect output via Resource.main_attrs.
Direct Known Subclasses
Collection, Product, ProductImage, ProductOption, ProductVariant, Search::Suggestion
Instance Attribute Summary collapse
-
#attrs ⇒ Hash
readonly
The normalized attribute hash.
-
#client ⇒ Showroom::Client?
The client that fetched this resource.
Class Method Summary collapse
-
.has_many(name, klass) ⇒ void
Defines a reader that wraps the array at
attrs[name]as instances ofklass. -
.has_one(name, klass) ⇒ void
Defines a reader that wraps the hash at
attrs[name]as an instance ofklass, or returnsnilwhen absent. -
.main_attr_keys ⇒ Array<String>
Returns the list of keys configured via Resource.main_attrs.
-
.main_attrs(*keys) ⇒ void
Declares which attribute keys are included in #inspect output.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Compares two resources by their underlying attribute hashes.
-
#[](key) ⇒ Object?
Raw access to an attribute by key.
-
#initialize(hash = {}) ⇒ Resource
constructor
Initializes a Resource from a Hash, normalizing all keys to strings.
-
#inspect ⇒ String
Returns a developer-friendly string showing Resource.main_attrs values.
-
#method_missing(name, *args) ⇒ Object?
Delegates attribute lookups to @attrs, and caches the method on first call.
- #respond_to_missing?(name, include_private = false) ⇒ Boolean
-
#to_h ⇒ Hash
Deep-converts the resource (and any nested resources) back to a plain Hash.
Constructor Details
#initialize(hash = {}) ⇒ Resource
Initializes a Resource from a Hash, normalizing all keys to strings.
24 25 26 |
# File 'lib/showroom/models/resource.rb', line 24 def initialize(hash = {}) @attrs = hash.transform_keys(&:to_s) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object?
Delegates attribute lookups to @attrs, and caches the method on first call.
115 116 117 118 119 120 121 122 123 |
# File 'lib/showroom/models/resource.rb', line 115 def method_missing(name, *args, &) key = name.to_s if @attrs.key?(key) self.class.define_method(name) { @attrs[key] } @attrs[key] else super end end |
Instance Attribute Details
#attrs ⇒ Hash (readonly)
Returns the normalized attribute hash.
16 17 18 |
# File 'lib/showroom/models/resource.rb', line 16 def attrs @attrs end |
#client ⇒ Showroom::Client?
Returns the client that fetched this resource.
19 20 21 |
# File 'lib/showroom/models/resource.rb', line 19 def client @client end |
Class Method Details
.has_many(name, klass) ⇒ void
This method returns an undefined value.
Defines a reader that wraps the array at attrs[name] as instances of klass.
50 51 52 53 54 55 56 57 |
# File 'lib/showroom/models/resource.rb', line 50 def has_many(name, klass) # rubocop:disable Naming/PredicatePrefix define_method(name) do @attrs[name.to_s] = Array(@attrs[name.to_s]).map do |item| item.is_a?(klass) ? item : klass.new(item) end @attrs[name.to_s] end end |
.has_one(name, klass) ⇒ void
This method returns an undefined value.
Defines a reader that wraps the hash at attrs[name] as an instance of klass, or returns nil when absent.
65 66 67 68 69 70 71 72 |
# File 'lib/showroom/models/resource.rb', line 65 def has_one(name, klass) # rubocop:disable Naming/PredicatePrefix define_method(name) do value = @attrs[name.to_s] return nil if value.nil? value.is_a?(klass) ? value : klass.new(value) end end |
.main_attr_keys ⇒ Array<String>
Returns the list of keys configured via main_attrs.
40 41 42 |
# File 'lib/showroom/models/resource.rb', line 40 def main_attr_keys @main_attrs || [] end |
.main_attrs(*keys) ⇒ void
This method returns an undefined value.
Declares which attribute keys are included in #inspect output.
33 34 35 |
# File 'lib/showroom/models/resource.rb', line 33 def main_attrs(*keys) @main_attrs = keys.map(&:to_s) end |
Instance Method Details
#==(other) ⇒ Boolean
Compares two resources by their underlying attribute hashes.
106 107 108 |
# File 'lib/showroom/models/resource.rb', line 106 def ==(other) other.is_a?(self.class) && other.attrs == @attrs end |
#[](key) ⇒ Object?
Raw access to an attribute by key.
79 80 81 |
# File 'lib/showroom/models/resource.rb', line 79 def [](key) @attrs[key.to_s] end |
#inspect ⇒ String
Returns a developer-friendly string showing main_attrs values.
93 94 95 96 97 98 99 100 |
# File 'lib/showroom/models/resource.rb', line 93 def inspect keys = self.class.main_attr_keys pairs = keys.filter_map do |k| value = @attrs[k] "#{k}: #{value.inspect}" if @attrs.key?(k) end "#<#{self.class.name} #{pairs.join(', ')}>" end |
#respond_to_missing?(name, include_private = false) ⇒ Boolean
128 129 130 |
# File 'lib/showroom/models/resource.rb', line 128 def respond_to_missing?(name, include_private = false) @attrs.key?(name.to_s) || super end |
#to_h ⇒ Hash
Deep-converts the resource (and any nested resources) back to a plain Hash.
86 87 88 |
# File 'lib/showroom/models/resource.rb', line 86 def to_h @attrs.transform_values { |v| deep_unwrap(v) } end |