enum_field 0.1.4 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +31 -0
- data/lib/enum_field/enumerated_attribute.rb +56 -0
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -80,6 +80,37 @@ You have some +AR+ like methods in enum classes
|
|
80
80
|
PhoneType.find(2) == PhoneType.commercial
|
81
81
|
PhoneType.find(123456) # will raise
|
82
82
|
|
83
|
+
It also mimics has_many :through behavior, for cases such as:
|
84
|
+
|
85
|
+
class Role
|
86
|
+
define_enum do |builder|
|
87
|
+
builder.member :admin
|
88
|
+
builder.member :manager
|
89
|
+
builder.member :employee
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class User
|
94
|
+
has_many_enumerated_attributes :roles, :through => UserRole
|
95
|
+
end
|
96
|
+
|
97
|
+
class UserRole < ActiveRecord::Base
|
98
|
+
belongs_to :user
|
99
|
+
enumerated_attribute :role
|
100
|
+
end
|
101
|
+
|
102
|
+
user = User.create
|
103
|
+
user.role = [Role.manager, Role.admin]
|
104
|
+
user.roles.include?(Role.admin) #will be true
|
105
|
+
user.roles.include?(Role.manager) #will be true
|
106
|
+
user.roles.include?(Role.employee) #will be false
|
107
|
+
user.role_ids.include?(Role.manager.id) #will be true
|
108
|
+
user.role_ids = [Role.employee.id]
|
109
|
+
user.roles.include?(Role.employee) #will be true
|
110
|
+
user.roles.include?(Role.admin) #will be false
|
111
|
+
|
112
|
+
|
113
|
+
|
83
114
|
== REQUIREMENTS:
|
84
115
|
|
85
116
|
* activerecord
|
@@ -11,6 +11,24 @@ module EnumField
|
|
11
11
|
# These added methods expect an object of class Role, and Role should provide a find class method.
|
12
12
|
# You could get this by using Enumerated mixin
|
13
13
|
#
|
14
|
+
# Similar to has_many :through in AR, it creates reader and writter methods to get enumerated atributes going through an
|
15
|
+
# intermediate model.
|
16
|
+
# For instance:
|
17
|
+
# <tt>
|
18
|
+
# class User
|
19
|
+
# has_many_enumerated_attributes :roles, :through => UserRole
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# class UserRole < ActiveRecord::Base
|
23
|
+
# belongs_to :user
|
24
|
+
# enumerated_attribute :role
|
25
|
+
# end
|
26
|
+
# </tt>
|
27
|
+
# This assumes a Role class, the UserRole AR class is there just to persist the one-to-many relationship.
|
28
|
+
# This will define roles, roles=, role_ids and role_ids= methods in User class
|
29
|
+
|
30
|
+
|
31
|
+
|
14
32
|
module EnumeratedAttribute
|
15
33
|
# Define an enumerated field of the AR class
|
16
34
|
# * +name_attribute+: the name of the field that will be added, for instance +role+
|
@@ -30,6 +48,44 @@ module EnumeratedAttribute
|
|
30
48
|
write_attribute(id_attribute, value ? value.id : nil)
|
31
49
|
end
|
32
50
|
end
|
51
|
+
|
52
|
+
alias belongs_to_enumerated_attribute enumerated_attribute
|
53
|
+
|
54
|
+
# Define a one-to-many association between an AR class and the enumerated
|
55
|
+
# * +association+: the name of the one-to-many association, for instance +roles+
|
56
|
+
# * +options+: Valid options are:
|
57
|
+
# * +through+ : the name of the AR class needed to persist the one-to-many association.
|
58
|
+
# Defaults to AR class in camelcase form plus enumerated class in camelcase form.
|
59
|
+
# * +class+: the enumerated class that will be instantiated +n+ times when +association+ method is called.
|
60
|
+
# Defaults to +association+ in singular camelcase form.
|
61
|
+
def has_many_enumerated_attributes(association, options = {})
|
62
|
+
enum_attr = association.to_s.singularize
|
63
|
+
klass = options[:class] || enum_attr.camelcase.constantize
|
64
|
+
through = options[:through] || (self.name + klass.name)
|
65
|
+
self_attribute = self.name.demodulize.underscore
|
66
|
+
association_ids = association.to_s.singularize + '_ids'
|
67
|
+
has_many_aux = through.demodulize.underscore.pluralize
|
68
|
+
|
69
|
+
has_many has_many_aux, {:class_name => through, :dependent => :destroy}
|
70
|
+
|
71
|
+
define_method(association) do
|
72
|
+
self.send(has_many_aux).map(&enum_attr.to_sym)
|
73
|
+
end
|
74
|
+
|
75
|
+
define_method(association.to_s + '=') do |values|
|
76
|
+
self.send(has_many_aux + '=', values.map{|g| through.constantize.new(self_attribute => self, enum_attr => g)})
|
77
|
+
end
|
78
|
+
|
79
|
+
define_method(association_ids) do
|
80
|
+
self.send(association).map(&:id)
|
81
|
+
end
|
82
|
+
|
83
|
+
define_method(association_ids + '=') do |values|
|
84
|
+
self.send(has_many_aux + '=', values.map{|g| g.to_i unless g.blank?}.compact.map{|g_id| through.constantize.new(self_attribute => self, enum_attr + '_id' => g_id) })
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
33
89
|
end
|
34
90
|
|
35
91
|
end
|