class Attributor::Model
Public Class Methods
check_option!(name, value)
click to toggle source
Calls superclass method
Attributor::Hash::check_option!
# File lib/attributor/types/model.rb, line 81 def self.check_option!(name, value) case name when :identity raise AttributorException, "Invalid identity type #{value.inspect}" unless value.is_a?(::Symbol) :ok # FIXME: ... actually do something smart, that doesn't break lazy attribute creation when :reference :ok # FIXME: ... actually do something smart when :dsl_compiler :ok # FIXME: ... actually do something smart when :dsl_compiler_options :ok else super end end
define_accessors(name)
click to toggle source
Define accessors for attribute of given name.
@param name [::Symbol] attribute name
# File lib/attributor/types/model.rb, line 58 def self.define_accessors(name) name = name.to_sym define_reader(name) define_writer(name) end
define_reader(name)
click to toggle source
# File lib/attributor/types/model.rb, line 64 def self.define_reader(name) module_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{name} @contents[:#{name}] end RUBY end
define_writer(name)
click to toggle source
# File lib/attributor/types/model.rb, line 72 def self.define_writer(name) context = ['assignment', "of(#{name})"].freeze module_eval do define_method(name.to_s + '=') do |value| set(name, value, context: context) end end end
example(context = nil, **values)
click to toggle source
# File lib/attributor/types/model.rb, line 101 def self.example(context = nil, **values) context ||= ["#{name || 'Struct'}-#{rand(10_000_000)}"] context = Array(context) if keys.any? result = new result.extend(ExampleMixin) result.lazy_attributes = example_contents(context, result, **values) else result = new end result end
generate_subcontext(context, subname)
click to toggle source
# File lib/attributor/types/model.rb, line 97 def self.generate_subcontext(context, subname) context + [subname] end
inherited(klass)
click to toggle source
# File lib/attributor/types/model.rb, line 31 def self.inherited(klass) k = key_type ka = key_attribute v = value_type va = value_attribute klass.instance_eval do @saved_blocks = [] @options = {} @keys = {} @key_type = k @value_type = v @key_attribute = ka @value_attribute = va @requirements = [] @cached_defaults = {} @error = false end end
new(data = nil)
click to toggle source
# File lib/attributor/types/model.rb, line 116 def initialize(data = nil) if data loaded = self.class.load(data) @contents = loaded.attributes else @contents = {} end end
Public Instance Methods
attributes()
click to toggle source
# File lib/attributor/types/model.rb, line 140 def attributes @contents end
dump(context: Attributor::DEFAULT_ROOT_CONTEXT, **_opts)
click to toggle source
# File lib/attributor/types/model.rb, line 165 def dump(context: Attributor::DEFAULT_ROOT_CONTEXT, **_opts) return CIRCULAR_REFERENCE_MARKER if @dumping @dumping = true attributes.each_with_object({}) do |(name, value), hash| attribute = self.class.attributes[name] # skip dumping undefined attributes unless attribute warn "WARNING: Trying to dump unknown attribute: #{name.inspect} with context: #{context.inspect}" next end hash[name.to_sym] = attribute.dump(value, context: context + [name], **_opts) end ensure @dumping = false end
method_missing(name, *args)
click to toggle source
Calls superclass method
# File lib/attributor/types/model.rb, line 153 def method_missing(name, *args) attribute_name = name.to_s attribute_name.chomp!('=') if self.class.attributes.key?(attribute_name.to_sym) self.class.define_accessors(attribute_name) return __send__(name, *args) end super end
respond_to_missing?(name, *)
click to toggle source
Calls superclass method
# File lib/attributor/types/model.rb, line 144 def respond_to_missing?(name, *) attribute_name = name.to_s attribute_name.chomp!('=') return true if self.class.attributes.key?(attribute_name.to_sym) super end
to_hash()
click to toggle source
This allows the splatting of these instances into method calls (top level hash conversion only)
# File lib/attributor/types/model.rb, line 185 def to_hash @contents end
validate(context = Attributor::DEFAULT_ROOT_CONTEXT)
click to toggle source
TODO: memoize validation results here, but only after rejiggering how we store the context.
Two calls to validate() with different contexts should return get the same errors, but with their respective contexts.
# File lib/attributor/types/model.rb, line 128 def validate(context = Attributor::DEFAULT_ROOT_CONTEXT) raise AttributorException, 'validation conflict' if @validating @validating = true context = [context] if context.is_a? ::String # Use the common, underlying attribute validation of the hash (which will use our _get_attr) # to know how to retrieve a value from a model (instead of a hash) validate_keys(context) ensure @validating = false end