Module: Jsapi::Meta::Model::Attributes::ClassMethods
- Defined in:
- lib/jsapi/meta/model/attributes/class_methods.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.
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 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/jsapi/meta/model/attributes/class_methods.rb', line 12 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 if accessors.include?(: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 end # Add method if accessors.include?(:add) define_method(add_method) do |argument = nil| try_modify_attribute!(name) do 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 end end end end 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 if accessors.include?(:reader) define_method(singular_name) do |key = nil| key = default_key if key.to_s.empty? send(name)[key_type_caster.cast(key)] end end if accessors.include?(:add) || accessors.include?(:writer) add_method = "add_#{singular_name}" value_type_caster = TypeCaster.new(value_type, values: values) # Attribute writer if accessors.include?(: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 end # Add method if accessors.include?(:add) define_method(add_method) do |key_or_value, value = nil| try_modify_attribute!(name) do 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? if instance_variable_defined?(instance_variable_name) instance_variable_get(instance_variable_name) else instance_variable_set(instance_variable_name, {}) end[key_type_caster.cast(key)] = value_type_caster.cast(value) end end end end else # Predicate method if values == [true, false] && accessors.include?(:reader) define_method("#{name}?") do value = instance_variable_get(instance_variable_name) value.nil? ? (default == true) || false : value end end # Attribute writer if accessors.include?(:writer) type_caster = TypeCaster.new(type, values: values, name: name) define_method("#{name}=") do |argument = nil| try_modify_attribute!(name) do instance_variable_set(instance_variable_name, type_caster.cast(argument)) end end end end # Attribute reader if accessors.include?(:reader) default = nil if default == :nil define_method(name) do value = instance_variable_get(instance_variable_name) value.nil? ? default : value end end end |
#attribute_names ⇒ Object
140 141 142 143 144 145 |
# File 'lib/jsapi/meta/model/attributes/class_methods.rb', line 140 def attribute_names names = @attribute_names || [] return names unless superclass.respond_to?(:attribute_names) superclass.attribute_names + names end |