/
class_methods.rb
85 lines (76 loc) · 2.04 KB
/
class_methods.rb
1
2
3
4
5
6
7
8
9
10
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
module Virtus
# Class methods that are added when you include Virtus
module ClassMethods
# Defines an attribute on an object's class
#
# @example
# class Book
# include Virtus
#
# attribute :title, String
# attribute :author, String
# attribute :published_at, DateTime
# attribute :page_count, Integer
# end
#
# @param [Symbol] name
# the name of an attribute
#
# @param [Class] type
# the type class of an attribute
#
# @param [#to_hash] options
# the extra options hash
#
# @return [self]
#
# @api public
def attribute(name, type, options = {})
attribute = Attribute.determine_type(type).new(name, options)
attribute.add_reader_method(self)
attribute.add_writer_method(self)
attributes << attribute
descendants.each { |descendant| descendant.attributes.reset }
self
end
# Returns all the attributes defined on a Class
#
# @example
# class User
# include Virtus
#
# attribute :name, String
# attribute :age, Integer
# end
#
# User.attributes # =>
#
# TODO: implement inspect so the output is not cluttered - solnic
#
# @return [AttributeSet]
#
# @api public
def attributes
@attributes ||= begin
superclass = self.superclass
parent = superclass.attributes if superclass.respond_to?(:attributes)
AttributeSet.new(parent)
end
end
private
# Hooks into const missing process to determine types of attributes
#
# It is used when an attribute is defined and a global class like String
# or Integer is provided as the type which needs to be mapped to
# Virtus::Attribute::String and Virtus::Attribute::Integer
#
# @param [String] name
#
# @return [Class]
#
# @api private
def const_missing(name)
Attribute.determine_type(name) || super
end
end # module ClassMethods
end # module Virtus