enum_field 0.1.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|