haz_enum 0.4.3 → 0.5.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 CHANGED
@@ -1,6 +1,108 @@
1
1
  = haz_enum
2
2
 
3
- Description goes here.
3
+ haz_enum is a ActiveRecord extension to allow associations to enumerations.
4
+
5
+ == Installation
6
+
7
+ haz_enum is hostet on rubygems.org, so yoou can just do
8
+
9
+ gem install haz_enum
10
+
11
+ or if you use bundler, just add the following line to your Gemfile:
12
+
13
+ gem "haz_enum"
14
+
15
+
16
+ == Example with renum
17
+
18
+ renum is a perfect library for enumerations in ruby (see http://github.com/duelinmarkers/renum). Here is a simple renum definition:
19
+
20
+ enum :Roles do
21
+ Admin()
22
+ Supervisor()
23
+ ContentManager()
24
+ end
25
+
26
+ in your AR-model you can now write
27
+
28
+ class User < ActiveRecord
29
+ has_enum :role
30
+ end
31
+
32
+ what you need is a column in your db named <code>role</code> with type <code>string</code>.
33
+
34
+ user = User.create(:role => Roles::Admin)
35
+ user.has_role?(Roles::Admin) => true
36
+ user.has_role?(Roles::Supervisor) => false
37
+
38
+ The example above realizes one role per user. But what if you want to have multiple Roles per user? Just change <code>has_enum</code> to <code>has_set</code> and rename the column to <code>roles</code>:
39
+
40
+ class User < ActiveRecord
41
+ has_set :roles
42
+ end
43
+
44
+ user = User.create(:roles => Roles::Admin)
45
+ user.has_role?(Roles::Admin) => true
46
+ user.has_role?(Roles::Supervisor) => false
47
+
48
+ or
49
+
50
+ user = User.create(:roles => [Roles::Admin, Roles::Supervisor])
51
+ user.has_role?(Roles::Admin) => true
52
+ user.has_role?(Roles::Supervisor) => true
53
+
54
+ now <code>roles</code> behaves just like an array, so you can also do
55
+
56
+ user = User.create(:roles => Roles::Admin)
57
+ user.roles << Roles::Supervisor
58
+ user.has_role?(Roles::Admin) => true
59
+ user.has_role?(Roles::Supervisor) => true
60
+
61
+ == Using bitfields
62
+
63
+ If you have an enum with many possible values you can switch from :yml to field_type :bitfield.
64
+
65
+ class User < ActiveRecord
66
+ has_set :roles, :field_type => :bitfield
67
+ end
68
+
69
+ Your db-column has to be an integer for field_type bitfield. If you use mysql with int(11) you are able to have up to 64 different values in your enumeration.
70
+
71
+ == You do not need renum
72
+
73
+ ...but it really makes sense to use this library. If you really do not want to use it you have to implement against an interface. Here is a simple ruby module example to get the same results as above for has_enum:
74
+
75
+ module Roles
76
+ class Admin; def self.name; "Admin"; end; end
77
+ class Supervisor; def self.name; "Supervisor"; end; end
78
+ class ContentManager; def self.name; "ContentManager"; end; end
79
+ end
80
+
81
+ You cannot use this for <code>has_set</code> and <code>field_type :yml</code> since you cannot dump anonymous classes. But you can use <code>field_type :bitfield</code>. Then your class could look something like that:
82
+
83
+ module Roles
84
+ class Admin
85
+ def self.bitfield_index; 1; end
86
+ end
87
+ class Supervisor
88
+ def self.bitfield_index; 2; end
89
+ end
90
+ class ContentManager
91
+ def self.bitfield_index; 3; end
92
+ end
93
+ class <<self
94
+ def values
95
+ Roles.constants.collect { |c| Roles.const_get(c) }
96
+ end
97
+ end
98
+ end
99
+
100
+ As you can see, your classes have to respond to <code>bitfield_index</code> and your wrapping module has to respond to values and return all available classes. So now you could do:
101
+
102
+ class User < ActiveRecord
103
+ has_enum :role, :field_type => :bitfield
104
+ end
105
+
4
106
 
5
107
  == Note on Patches/Pull Requests
6
108
 
data/Rakefile CHANGED
@@ -10,8 +10,9 @@ begin
10
10
  gem.email = "andi@galaxycats.com"
11
11
  gem.homepage = "http://github.com/galaxycats/haz_enum"
12
12
  gem.authors = ["thyphoon"]
13
- gem.add_dependency "activerecord", ">= 3.0.0.beta3"
14
- gem.add_development_dependency "rspec", ">= 1.2.9"
13
+ gem.add_dependency "activerecord", "~> 3.0.0"
14
+ gem.add_development_dependency "rspec", "~> 1.3.0"
15
+ gem.add_development_dependency "renum", "~> 1.3.1"
15
16
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
17
  end
17
18
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.3
1
+ 0.5.0
data/haz_enum.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{haz_enum}
8
- s.version = "0.4.3"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["thyphoon"]
12
- s.date = %q{2010-06-29}
12
+ s.date = %q{2010-09-16}
13
13
  s.description = %q{use has_set and has_enum in your ActiveRecord models if you want to have one (has_enum) value from a defined enumeration or more (has_set))}
14
14
  s.email = %q{andi@galaxycats.com}
15
15
  s.extra_rdoc_files = [
@@ -49,15 +49,18 @@ Gem::Specification.new do |s|
49
49
  s.specification_version = 3
50
50
 
51
51
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
- s.add_runtime_dependency(%q<activerecord>, [">= 3.0.0.beta3"])
53
- s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
52
+ s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.0"])
53
+ s.add_development_dependency(%q<rspec>, ["~> 1.3.0"])
54
+ s.add_development_dependency(%q<renum>, ["~> 1.3.1"])
54
55
  else
55
- s.add_dependency(%q<activerecord>, [">= 3.0.0.beta3"])
56
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
56
+ s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
57
+ s.add_dependency(%q<rspec>, ["~> 1.3.0"])
58
+ s.add_dependency(%q<renum>, ["~> 1.3.1"])
57
59
  end
58
60
  else
59
- s.add_dependency(%q<activerecord>, [">= 3.0.0.beta3"])
60
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
61
+ s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
62
+ s.add_dependency(%q<rspec>, ["~> 1.3.0"])
63
+ s.add_dependency(%q<renum>, ["~> 1.3.1"])
61
64
  end
62
65
  end
63
66
 
data/lib/haz_enum/enum.rb CHANGED
@@ -25,6 +25,10 @@ module HazEnum
25
25
  end
26
26
  end
27
27
 
28
+ define_method "has_#{enum_name}?" do |enum|
29
+ send(enum_name) == enum
30
+ end
31
+
28
32
  define_method "#{enum_name}_changed?" do
29
33
  send("#{enum_column}_changed?")
30
34
  end if enum_name != enum_column
data/lib/haz_enum/set.rb CHANGED
@@ -2,7 +2,7 @@ module HazEnum
2
2
  module Set
3
3
  def has_set(set_name, options={})
4
4
 
5
- field_type = options.has_key?(:field_type) ? options[:field_type].to_s : "bitfield"
5
+ field_type = options.has_key?(:field_type) ? options[:field_type].to_s : "yml"
6
6
  set_column = options.has_key?(:column_name) ? options[:column_name].to_s : "#{set_name}_#{field_type}"
7
7
  enum_class = options.has_key?(:class_name) ? options[:class_name].to_s.camelize.constantize : set_name.to_s.camelize.constantize
8
8
  separator = options.has_key?(:separator) ? options[:separator].to_s : ", "
@@ -15,11 +15,14 @@ module HazEnum
15
15
  end
16
16
 
17
17
  define_method("#{set_name}=") do |value|
18
+ value = [value].flatten
18
19
  value.collect! { |val| val.is_a?(String) ? val.constantize : val }.compact! if value.is_a?(Array)
19
20
  value.instance_variable_set("@separator", separator)
20
21
  class <<value
21
- define_method :to_s do
22
- self.join(@separator)
22
+ define_method :human do
23
+ self.collect do |enum|
24
+ enum.respond_to?(:model_name) ? enum.model_name.human : enum.name
25
+ end.join(@separator)
23
26
  end
24
27
  yield if block_given?
25
28
  end
data/lib/haz_enum.rb CHANGED
@@ -2,6 +2,11 @@ require "haz_enum/enum"
2
2
  require "haz_enum/set"
3
3
 
4
4
  module HazEnum
5
+ class <<self
6
+ def available_field_types_for_sets
7
+ [:yml, :bitfield]
8
+ end
9
+ end
5
10
  end
6
11
 
7
12
  ActiveRecord::Base.extend HazEnum::Enum
data/spec/enum_spec.rb CHANGED
@@ -21,6 +21,12 @@ describe "HazEnum" do
21
21
  ClassWithEnum.new(:product => "Silver").product.should be(Products::Silver)
22
22
  end
23
23
 
24
+ it "should have has_<association>? method" do
25
+ class_with_enum = ClassWithEnum.new(:product => "Silver")
26
+ class_with_enum.has_product?(Products::Silver).should == true
27
+ class_with_enum.has_product?(Products::Gold).should == false
28
+ end
29
+
24
30
  it "should not be able to set enum-attribute by colum-name via hash in initializer" do
25
31
  ClassWithCustomNameEnum.new(:custom_name => Products::Silver).product.should_not be(Products::Silver)
26
32
  ClassWithCustomNameEnum.new(:custom_name => Products::Silver.name).product.should_not be(Products::Silver)
@@ -59,6 +65,11 @@ describe "HazEnum" do
59
65
  enum_mixin.errors[:product].size.should > 0
60
66
  end
61
67
 
68
+ it "should work without renum (just ruby module with classes)" do
69
+ role_enum = ClassWithEnum.new(:module_role => ModuleRoles::Admin)
70
+ role_enum.has_module_role?(ModuleRoles::Admin).should == true
71
+ end
72
+
62
73
  after(:all) do
63
74
  teardown_db
64
75
  end
data/spec/set_spec.rb CHANGED
@@ -21,6 +21,12 @@ describe "HazEnum" do
21
21
  ClassWithSet.new.roles.should == []
22
22
  end
23
23
 
24
+ it "should have has_<association>? method" do
25
+ class_with_enum = ClassWithSet.new(:roles => Roles::Admin)
26
+ class_with_enum.has_role?(Roles::Admin).should == true
27
+ class_with_enum.has_role?(Roles::User).should == false
28
+ end
29
+
24
30
  it "should be able to save values as yml" do
25
31
  YmlSet.new(:roles => [Roles::User, Roles::Admin]).roles[1].should be(Roles::Admin)
26
32
  yml_set = YmlSet.create(:roles => [Roles::User, Roles::Admin])
@@ -67,6 +73,16 @@ describe "HazEnum" do
67
73
  extended.to_s.should == "Admin, Supervisor, User"
68
74
  end
69
75
 
76
+ it "should be able to work without renum and bitfield" do
77
+ roles_set = ClassWithSet.new(:module_bitfield_roles => [ModuleBitfieldRoles::Admin, ModuleBitfieldRoles::Supervisor])
78
+ roles_set.has_module_bitfield_role?(ModuleBitfieldRoles::Admin).should == true
79
+ roles_set.has_module_bitfield_role?(ModuleBitfieldRoles::Supervisor).should == true
80
+ roles_set.save
81
+ roles_set.reload
82
+ roles_set.has_module_bitfield_role?(ModuleBitfieldRoles::Admin).should == true
83
+ roles_set.has_module_bitfield_role?(ModuleBitfieldRoles::Supervisor).should == true
84
+ end
85
+
70
86
  after(:all) do
71
87
  teardown_db
72
88
  end
data/spec/spec_helper.rb CHANGED
@@ -54,13 +54,36 @@ end
54
54
 
55
55
  enum :Fakes, [:NOT_DEFINIED]
56
56
  enum :Products, [:Silver, :Gold, :Titanium]
57
-
58
57
  enum :Roles, [:Admin, :Supervisor, :User]
59
58
 
59
+ module ModuleRoles
60
+ class Admin; def self.name; "Admin"; end; end
61
+ class Supervisor; def self.name; "Supervisor"; end; end
62
+ class ContentManager; def self.name; "ContentManager"; end; end
63
+ end
64
+
65
+ module ModuleBitfieldRoles
66
+ class Admin
67
+ def self.bitfield_index; 1; end
68
+ end
69
+ class Supervisor
70
+ def self.bitfield_index; 2; end
71
+ end
72
+ class ContentManager
73
+ def self.bitfield_index; 3; end
74
+ end
75
+ class <<self
76
+ def values
77
+ ModuleBitfieldRoles.constants.collect { |c| ModuleBitfieldRoles.const_get(c) }
78
+ end
79
+ end
80
+ end
81
+
60
82
  setup_db # Init the database for class creation
61
83
 
62
84
  class ClassWithEnum < ActiveRecord::Base
63
85
  has_enum :product
86
+ has_enum :module_role
64
87
  end
65
88
 
66
89
  class ClassWithCustomNameEnum < ActiveRecord::Base
@@ -74,6 +97,8 @@ class ClassWithSet < ActiveRecord::Base
74
97
  extended_roles.collect(&:name).join(", ")
75
98
  end
76
99
  end
100
+ has_set :module_roles
101
+ has_set :module_bitfield_roles, :field_type => :bitfield
77
102
  end
78
103
 
79
104
  class YmlSet < ActiveRecord::Base
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 4
8
- - 3
9
- version: 0.4.3
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - thyphoon
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-29 00:00:00 +02:00
17
+ date: 2010-09-16 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -22,14 +22,13 @@ dependencies:
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ">="
25
+ - - ~>
26
26
  - !ruby/object:Gem::Version
27
27
  segments:
28
28
  - 3
29
29
  - 0
30
30
  - 0
31
- - beta3
32
- version: 3.0.0.beta3
31
+ version: 3.0.0
33
32
  type: :runtime
34
33
  version_requirements: *id001
35
34
  - !ruby/object:Gem::Dependency
@@ -37,15 +36,29 @@ dependencies:
37
36
  prerelease: false
38
37
  requirement: &id002 !ruby/object:Gem::Requirement
39
38
  requirements:
40
- - - ">="
39
+ - - ~>
41
40
  - !ruby/object:Gem::Version
42
41
  segments:
43
42
  - 1
44
- - 2
45
- - 9
46
- version: 1.2.9
43
+ - 3
44
+ - 0
45
+ version: 1.3.0
47
46
  type: :development
48
47
  version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: renum
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 1
57
+ - 3
58
+ - 1
59
+ version: 1.3.1
60
+ type: :development
61
+ version_requirements: *id003
49
62
  description: use has_set and has_enum in your ActiveRecord models if you want to have one (has_enum) value from a defined enumeration or more (has_set))
50
63
  email: andi@galaxycats.com
51
64
  executables: []