class AnsibleTowerClient::HashModel
A core base class for JSON wrapper classes. The original data can be a JSON string or a hash parsed from JSON string. Similar to OpenStruct, it auto generates access methods base on key names. If the value is also a hash, it too gets converted to an instance of model class.
This is an abstract class.
Public Class Methods
# File lib/ansible_tower_client/hash_model.rb, line 84 def initialize(json_or_hash) raw_hash = json_or_hash.kind_of?(Hash) ? json_or_hash : JSON.parse(json_or_hash) @data = Hash[raw_hash.collect { |key, value| [key, self.class.send(:convert_value, key, value, self)] }] end
Private Class Methods
# File lib/ansible_tower_client/hash_model.rb, line 72 def add_accessor_methods(method, key) return if modelized_list.include?(method.to_s) method = "_#{method}" if instance_methods.include?(method.to_sym) class_eval { define_method(method) { @data[key] } } attr_model(method) return unless generate_writer? class_eval { define_method("#{method}=") { |val| @data[key] = val } } end
Should values of this attribute be excluded from converting to model objects
Default to false, to be overridden by subclasses.
# File lib/ansible_tower_client/hash_model.rb, line 33 def attr_excluded?(_attr_name) false end
Declare attributes that need to be converted to Model
# File lib/ansible_tower_client/hash_model.rb, line 38 def attr_model(*attrs) # Merge the declared attributes to the modelized list @modelized_list = modelized_list | Set.new(attrs.map(&:to_s)) end
# File lib/ansible_tower_client/hash_model.rb, line 48 def convert_value(key, value, parent) method = key_to_attribute(key).gsub(/\W/, '_') # replace all unqualified characters for method and class names new_val = if attr_excluded?(method) value else # Must deal with nested models case value when Array value.collect do |elem| elem.kind_of?(Hash) ? parent.send(:hash_to_model, method.camelize.singularize, elem) : elem end when Hash parent.send(:hash_to_model, method.camelize, value) else value end end add_accessor_methods(method, key) new_val end
Should setter methods be automatically created?
Default to true, to be overridden by subclasses.
# File lib/ansible_tower_client/hash_model.rb, line 25 def generate_writer? true end
Convert a key to a model class attribute which must be a qualified ruby method name key is from the original JSON or Hash object
This is the default implementation, to be overridden by subclasses.
# File lib/ansible_tower_client/hash_model.rb, line 17 def key_to_attribute(key) key.to_s.underscore end
Return the list of modelized attributes
# File lib/ansible_tower_client/hash_model.rb, line 44 def modelized_list @modelized_list ||= Set.new end
Public Instance Methods
# File lib/ansible_tower_client/hash_model.rb, line 111 def ==(other) return false unless other.kind_of?(HashModel) to_h == other.to_h end
# File lib/ansible_tower_client/hash_model.rb, line 89 def [](key) @data[key] end
# File lib/ansible_tower_client/hash_model.rb, line 105 def inspect string = "<#{self.class} " string << @data.collect { |key, value| "#{self.class.send(:key_to_attribute, key)}=#{value.inspect}" }.join(", ") string << ">" end
# File lib/ansible_tower_client/hash_model.rb, line 93 def to_h Hash[@data.collect { |key, value| [key, value_to_hash(value)] }] end
# File lib/ansible_tower_client/hash_model.rb, line 99 def to_json to_h.to_json end
Private Instance Methods
Convert a hash to an instance of nested model class
This is the default implementation; the resulting object is based on HashModel
To be overridden by subclasses
# File lib/ansible_tower_client/hash_model.rb, line 133 def hash_to_model(klass_name, hash) model_klass = if self.class.const_defined?("#{self.class}::#{klass_name}") self.class.const_get(klass_name) else self.class.const_set(klass_name, Class.new(HashModel)) end model_klass.new(hash) end
# File lib/ansible_tower_client/hash_model.rb, line 120 def value_to_hash(value) case value when HashModel, Hash then value.to_h when Array then value.collect { |elem| elem.kind_of?(HashModel) ? elem.to_h : elem } else value end end