Module: Jsapi::Meta::Base::Attributes
- Included in:
- Model
- Defined in:
- lib/jsapi/meta/base/attributes.rb
Constant Summary collapse
- DEFAULT_ARRAY =
[].freeze
- DEFAULT_HASH =
{}.freeze
Instance Method Summary collapse
-
#attribute(name, type = Object, default: nil, default_key: nil, keys: nil, read_only: false, values: nil) ⇒ Object
Defines an attribute.
- #attribute_names ⇒ Object
Instance Method Details
#attribute(name, type = Object, default: nil, default_key: nil, keys: nil, read_only: false, 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 126 127 128 |
# File 'lib/jsapi/meta/base/attributes.rb', line 11 def attribute(name, type = Object, default: nil, default_key: nil, keys: nil, read_only: false, values: nil) (@attribute_names ||= []) << name.to_sym instance_variable_name = "@#{name}" case type when Array # General default default ||= DEFAULT_ARRAY unless read_only 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 # 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 end when Hash singular_name = name.to_s.singularize key_type, value_type = type.first key_type_caster = TypeCaster.new(key_type, values: keys, name: 'key') # General default default ||= DEFAULT_HASH # 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 unless read_only 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 # 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 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] unless read_only 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 end |
#attribute_names ⇒ Object
130 131 132 133 134 135 |
# File 'lib/jsapi/meta/base/attributes.rb', line 130 def attribute_names names = @attribute_names || [] return names unless superclass.respond_to?(:attribute_names) superclass.attribute_names + names end |