haz_enum 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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: []