Module: Jsapi::Meta::Model::Attributes
- Included in:
- Base
- Defined in:
- lib/jsapi/meta/model/attributes.rb
Constant Summary collapse
- DEFAULT_ARRAY =
[].freeze
- DEFAULT_HASH =
{}.freeze
Instance Method Summary collapse
-
#attribute(name, type = Object, accessors: %i[add reader writer],, default: nil, default_key: nil, keys: nil, values: nil) ⇒ Object
Defines an attribute.
- #attribute_names ⇒ Object
Instance Method Details
#attribute(name, type = Object, accessors: %i[add reader writer],, default: nil, default_key: nil, keys: nil, values: nil) ⇒ Object
Defines an attribute.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/jsapi/meta/model/attributes.rb', line 11 def attribute(name, type = Object, accessors: i[add reader writer], default: nil, default_key: nil, keys: nil, values: nil) (@attribute_names ||= []) << name.to_sym instance_variable_name = "@#{name}" case type when Array # General default default ||= DEFAULT_ARRAY if accessors.include?(:add) || accessors.include?(:writer) singular_name = name.to_s.singularize add_method = "add_#{singular_name}" type_caster = TypeCaster.new(type.first, values: values, name: singular_name) # Attribute writer define_method("#{name}=") do |argument| instance_variable_set(instance_variable_name, []).tap do Array.wrap(argument).each { |element| send(add_method, element) } end end if accessors.include?(:writer) # Add method define_method(add_method) do |argument = nil| type_caster.cast(argument).tap do |casted_argument| if instance_variable_defined?(instance_variable_name) instance_variable_get(instance_variable_name) else instance_variable_set(instance_variable_name, []) end << casted_argument attribute_changed(name) end end if accessors.include?(:add) end when Hash # General default default ||= DEFAULT_HASH singular_name = name.to_s.singularize key_type, value_type = type.first key_type_caster = TypeCaster.new(key_type, values: keys, name: 'key') # Lookup method define_method(singular_name) do |key = nil| key = default_key if key.to_s.empty? send(name)[key_type_caster.cast(key)] end if accessors.include?(:reader) if accessors.include?(:add) || accessors.include?(:writer) add_method = "add_#{singular_name}" value_type_caster = TypeCaster.new(value_type, values: values) # Attribute writer define_method("#{name}=") do |argument| instance_variable_set(instance_variable_name, {}).tap do Hash(argument).each { |key, value| send(add_method, key, value) } end end if accessors.include?(:writer) # Add method define_method(add_method) do |key_or_value, value = nil| if value.nil? && default_key key = default_key value = key_or_value else key = key_or_value key = default_key if key.to_s.empty? end raise ArgumentError, "key can't be blank" if key.to_s.empty? casted_key = key_type_caster.cast(key) casted_value = value_type_caster.cast(value) if instance_variable_defined?(instance_variable_name) instance_variable_get(instance_variable_name) else instance_variable_set(instance_variable_name, {}) end[casted_key] = casted_value attribute_changed(name) casted_value end if accessors.include?(:add) end else # Predicate method define_method("#{name}?") do value = instance_variable_get(instance_variable_name) value.nil? ? default || false : value end if values == [true, false] && accessors.include?(:reader) if accessors.include?(:writer) type_caster = TypeCaster.new(type, values: values, name: name) # Attribute writer define_method("#{name}=") do |argument = nil| type_caster.cast(argument).tap do |casted_value| instance_variable_set(instance_variable_name, casted_value) attribute_changed(name) end end end end # Attribute reader define_method(name) do value = instance_variable_get(instance_variable_name) value.nil? ? default : value end if accessors.include?(:reader) end |
#attribute_names ⇒ Object
127 128 129 130 131 132 |
# File 'lib/jsapi/meta/model/attributes.rb', line 127 def attribute_names names = @attribute_names || [] return names unless superclass.respond_to?(:attribute_names) superclass.attribute_names + names end |