module MyData::Resource
Constants
- ALLOWED_ATTRIBUTE_OPTS
Public Class Methods
new(attrs = {})
click to toggle source
# File lib/my_data/resource.rb, line 130 def initialize(attrs = {}) self.attributes = attrs end
Public Instance Methods
attr_mappings(name, type, opts)
click to toggle source
# File lib/my_data/resource.rb, line 91 def attr_mappings(name, type, opts) resource = if type == :resource klass_name = opts[:class_name].presence || name "MyData::Resources::#{klass_name}".constantize end @mappings[name] = { type: type, resource: resource, collection: opts[:collection], collection_element_name: opts[:collection_element_name] } end
attribute(name, type, opts = {})
click to toggle source
@param name [String] the name of the attribute @param type [Symbol] the type of the attribute (:string, :integer, etc) @param opts [Hash] options for custom parsing @option class_name [String] the name of the resource @option collection [Boolean] when the required attribute is a collection @option collection_element_name [String] when we set collection_element_name
we nested the elements of collection with that name
# File lib/my_data/resource.rb, line 50 def attribute(name, type, opts = {}) name = name.to_s raise "Wrong type: #{name}: #{type}" unless MyData::TypeCaster.valid_type?(type) if opts.any? { |k, _| !ALLOWED_ATTRIBUTE_OPTS.include?(k) } raise "Option not supported: #{name}: #{opts.keys - ALLOWED_ATTRIBUTE_OPTS}" end @attributes.push(name) attr_mappings(name, type, opts) define_attr_getter name, collection: opts[:collection] define_attr_setter name, collection: opts[:collection] end
attribute_names()
click to toggle source
# File lib/my_data/resource.rb, line 134 def attribute_names @attribute_names ||= self.class.attributes end
attributes()
click to toggle source
# File lib/my_data/resource.rb, line 138 def attributes attribute_names.reduce({}) do |hash, name| hash.merge!(name => public_send(name)) end end
attributes=(attrs)
click to toggle source
# File lib/my_data/resource.rb, line 144 def attributes=(attrs) attrs = attrs.respond_to?(:attributes) ? attrs.attributes : attrs attrs.each do |key, value| next unless attribute_names.include?(key.to_s) public_send("#{key}=", value) end attributes end
container_tag(name, opts = {})
click to toggle source
# File lib/my_data/resource.rb, line 27 def container_tag(name, opts = {}) @container[:name] = name @container[:attributes] = opts end
define_attr_getter(name, collection: false)
click to toggle source
# File lib/my_data/resource.rb, line 106 def define_attr_getter(name, collection: false) define_method name do value = instance_variable_get("@#{name}") collection && value.nil? ? [] : value end end
define_attr_setter(name, collection: false)
click to toggle source
# File lib/my_data/resource.rb, line 114 def define_attr_setter(name, collection: false) define_method "#{name}=" do |value| type, resource = self.class.mappings[name].values_at(:type, :resource) type_casted_value = if collection value.map { |val| MyData::TypeCaster.cast(value: val, type: type, resource: resource) } else MyData::TypeCaster.cast(value: value, type: type, resource: resource) end instance_variable_set("@#{name}", type_casted_value) end end
inspect()
click to toggle source
# File lib/my_data/resource.rb, line 66 def inspect format_attrs = attributes.map do |name| mapping = mappings[name] type = mapping[:type] == :resource ? mapping[:resource].name : mapping[:type] type = mapping[:collection] ? "[#{type}]" : type "#{name}: #{type}" end "#{name} #{format_attrs.join(", ")}" end
resources()
click to toggle source
# File lib/my_data/resource.rb, line 156 def resources attributes.select { |k, _| self.class.mappings[k][:resource] }.to_h end
serializable_hash(*args) { |key, value| ... }
click to toggle source
Calls superclass method
# File lib/my_data/resource.rb, line 174 def serializable_hash(*args) hash = super if block_given? hash.each { |key, value| hash[key] = yield(key, value) } else hash.each do |key, value| hash[key] = value.serializable_hash if value.respond_to?(:serializable_hash) end end hash end
to_xml()
click to toggle source
# File lib/my_data/resource.rb, line 188 def to_xml generator = MyData::XmlGenerator.new(self) generator.to_xml end
valid?()
click to toggle source
Calls superclass method
# File lib/my_data/resource.rb, line 160 def valid? is_valid = super && resources.values.flatten.compact.map(&:valid?).all? return true if is_valid add_nested_errors false end
xsd_complex_type()
click to toggle source
# File lib/my_data/resource.rb, line 39 def xsd_complex_type xsd_resource_attributes(name, :complex_type) end
xsd_doc()
click to toggle source
# File lib/my_data/resource.rb, line 32 def xsd_doc doc_name, doc = MyData::Xsd::Structure.doc(name) container_tag(doc_name, doc.attributes) xsd_resource_attributes(name, :doc) end
xsd_resource_attributes(name, type)
click to toggle source
# File lib/my_data/resource.rb, line 80 def xsd_resource_attributes(name, type) MyData::Xsd::Structure.resource_attributes(name, type).each do |attrs| e_name, type, opts = attrs required = opts.delete :required attribute(e_name, type, opts) validates_presence_of e_name if required end end
Private Instance Methods
add_nested_errors()
click to toggle source
# File lib/my_data/resource.rb, line 195 def add_nested_errors resources.compact.each do |k, resource| rs = resource.is_a?(Array) ? resource : [resource] rs.reject(&:valid?).each do |r| errors.add(k, :invalid_resource, message: r.errors.full_messages.join(", ")) end end end