Class: Virtus::Attributes::Attribute

Inherits:
Object
  • Object
show all
Defined in:
lib/virtus/attributes/attribute.rb

Direct Known Subclasses

Object

Constant Summary collapse

OPTIONS =
[ :primitive, :complex, :accessor, :reader, :writer ].freeze
DEFAULT_ACCESSOR =
:public.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, model, options = {}) ⇒ Attribute

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initializes an attribute instance

Parameters:

  • name (Symbol)

    the name of an attribute

  • model (Class)

    the object’s class

  • options (Hash) (defaults to: {})

    hash of extra options which overrides defaults set on an attribute class



105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/virtus/attributes/attribute.rb', line 105

def initialize(name, model, options = {})
  @name    = name
  @model   = model
  @options = self.class.options.merge(options).freeze

  @instance_variable_name = "@#{@name}".freeze

  default_accessor   = @options.fetch(:accessor, DEFAULT_ACCESSOR)
  @reader_visibility = @options.fetch(:reader, default_accessor)
  @writer_visibility = @options.fetch(:writer, default_accessor)

  _create_reader
  _create_writer
end

Instance Attribute Details

#instance_variable_nameObject (readonly)

Returns the value of attribute instance_variable_name.



4
5
6
# File 'lib/virtus/attributes/attribute.rb', line 4

def instance_variable_name
  @instance_variable_name
end

#modelObject (readonly)

Returns the value of attribute model.



4
5
6
# File 'lib/virtus/attributes/attribute.rb', line 4

def model
  @model
end

#nameObject (readonly)

Returns the value of attribute name.



4
5
6
# File 'lib/virtus/attributes/attribute.rb', line 4

def name
  @name
end

#optionsObject (readonly)

Returns the value of attribute options.



4
5
6
# File 'lib/virtus/attributes/attribute.rb', line 4

def options
  @options
end

#reader_visibilityObject (readonly)

Returns the value of attribute reader_visibility.



4
5
6
# File 'lib/virtus/attributes/attribute.rb', line 4

def reader_visibility
  @reader_visibility
end

#writer_visibilityObject (readonly)

Returns the value of attribute writer_visibility.



4
5
6
# File 'lib/virtus/attributes/attribute.rb', line 4

def writer_visibility
  @writer_visibility
end

Class Method Details

.accept_options(*args) ⇒ Object

Defines which options are valid for a given attribute class.

Example:

class MyAttribute < Virtus::Attributes::Object
  accept_options :foo, :bar
end


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/virtus/attributes/attribute.rb', line 31

def accept_options(*args)
  accepted_options.concat(args)

  # create methods for each new option
  args.each do |attribute_option|
    class_eval <<-RUBY, __FILE__, __LINE__ + 1
    def self.#{attribute_option}(value = Undefined)          # def self.unique(value = Undefined)
      return @#{attribute_option} if value.equal?(Undefined) #   return @unique if value.equal?(Undefined)
      @#{attribute_option} = value                           #   @unique = value
    end                                                      # end
    RUBY
  end

  descendants.each { |descendant| descendant.accepted_options.concat(args) }
end

.accepted_optionsArray

Returns an array of valid options

Returns:

  • (Array)

    the array of valid option names



18
19
20
# File 'lib/virtus/attributes/attribute.rb', line 18

def accepted_options
  @accepted_options ||= []
end

.descendantsArray

Returns all the descendant classes

Returns:

  • (Array)

    the array of descendants



53
54
55
# File 'lib/virtus/attributes/attribute.rb', line 53

def descendants
  @descendants ||= []
end

.inherited(descendant) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Adds descendant to descendants array and inherits default options



75
76
77
78
79
# File 'lib/virtus/attributes/attribute.rb', line 75

def inherited(descendant)
  descendants << descendant
  descendant.accepted_options.concat(accepted_options)
  options.each { |key, value| descendant.send(key, value) }
end

.optionsHash

Returns default options hash for a give attribute class.

Returns:

  • (Hash)

    a hash of default option values



63
64
65
66
67
68
69
70
# File 'lib/virtus/attributes/attribute.rb', line 63

def options
  options = {}
  accepted_options.each do |method|
    value = send(method)
    options[method] = value unless value.nil?
  end
  options
end

Instance Method Details

#_create_readerObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates an attribute reader method



183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/virtus/attributes/attribute.rb', line 183

def _create_reader
  model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
    chainable(:attribute) do
      #{reader_visibility}

      def #{name}
        return #{instance_variable_name} if defined?(#{instance_variable_name})
        attribute = self.class.attributes[#{name.inspect}]
      #{instance_variable_name} = attribute ? attribute.get(self) : nil
      end
    end
  RUBY

end

#_create_writerObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates an attribute writer method



201
202
203
204
205
206
207
208
209
210
211
# File 'lib/virtus/attributes/attribute.rb', line 201

def _create_writer
  model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
    chainable(:attribute) do
      #{writer_visibility}

      def #{name}=(value)
        self.class.attributes[#{name.inspect}].set(self, value)
      end
    end
  RUBY
end

#complex?TrueClass, FalseClass

Returns if an attribute is a complex one.

Returns:

  • (TrueClass, FalseClass)


89
90
91
# File 'lib/virtus/attributes/attribute.rb', line 89

def complex?
  options[:complex]
end

#get(model) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns value of an attribute for the given model



154
155
156
# File 'lib/virtus/attributes/attribute.rb', line 154

def get(model)
  get!(model)
end

#get!(model) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the instance variable of the attribute



161
162
163
# File 'lib/virtus/attributes/attribute.rb', line 161

def get!(model)
  model.instance_variable_get(instance_variable_name)
end

#primitive?(value) ⇒ TrueClass, FalseClass

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns if the given value’s class is an attribute’s primitive

Returns:

  • (TrueClass, FalseClass)


125
126
127
# File 'lib/virtus/attributes/attribute.rb', line 125

def primitive?(value)
  value.kind_of?(self.class.primitive)
end

#set(model, value) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Sets the value on the model



168
169
170
171
# File 'lib/virtus/attributes/attribute.rb', line 168

def set(model, value)
  return if value.nil?
  set!(model, typecast(value, model))
end

#set!(model, value) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Sets instance variable of the attribute



176
177
178
# File 'lib/virtus/attributes/attribute.rb', line 176

def set!(model, value)
  model.instance_variable_set(instance_variable_name, value)
end

#typecast(value, model = nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Converts the given value to the primitive type unless it’s already the primitive or nil

Parameters:

  • value (Object)

    the value



136
137
138
139
140
141
142
# File 'lib/virtus/attributes/attribute.rb', line 136

def typecast(value, model = nil)
  if value.nil? || primitive?(value)
    value
  else
    typecast_to_primitive(value)
  end
end

#typecast_to_primitive(value, model) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Converts the given value to the primitive type



147
148
149
# File 'lib/virtus/attributes/attribute.rb', line 147

def typecast_to_primitive(value, model)
  value
end