simple_enums 0.1.1

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/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in simple_enum.gemspec
4
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,79 @@
1
+ =SimpleEnum
2
+
3
+ == Description
4
+ Simple Enum is a simple and useful plugin for using enum attribute.
5
+
6
+ * version 0.23
7
+ * by Caryl
8
+
9
+ == Requirements
10
+
11
+ * Rails 2.2 or greater
12
+
13
+ ==Installation
14
+
15
+ ./script/plugin install git://github.com/caryl/simple_enum.git
16
+
17
+ ==Getting Started
18
+
19
+ Example:
20
+ class User
21
+ include SimpleEnum
22
+ has_enum :status, :enums => [[:unactived, 0, "未激活"],[:normal, 1, "正常"],[:locked, 2, "已锁定"]], \
23
+ :column => :status_id, :default => :normal
24
+ end
25
+ options:
26
+ has_enum name, enums[, column][, default]
27
+ * name: enum name
28
+ * enum: a array to define enums, each enum defined by [key(symbol), value(integer), human_name(string)]
29
+ * column: optional, must be a column, attr_accessor or a getter and setter method pair
30
+ * default is name + '_id'
31
+ * default: enum's default value, can assigned by a symbol(key) integer(value) or string(human name)
32
+ * default is the first enum
33
+
34
+ =Usage
35
+
36
+ This will define the following methods dynamically:
37
+
38
+ ==class methods:
39
+
40
+ * User.status_enums => [[:unactived, 0, "未激活"],[:normal, 1, "正常"],[:locked, 2, "已锁定"]]
41
+
42
+ * User.options_for_status => [["正常", 1], ["草稿", 0], ["锁定回复", 2], ["隐藏", 3]]
43
+
44
+ * User.status_name(:normal) => "正常" #return enum's human name
45
+ * params: array, symbol, integer, string or array
46
+
47
+ * User.status_value(:normal) => 1 #return enum value
48
+ * params: array, symbol, integer, string or array
49
+
50
+ * User.new => #default value has been set: user.status == 1
51
+
52
+ * User.status_is(:normal) => same as User.status_in(:normal)
53
+
54
+ ==instance methods:
55
+
56
+ * user.status => #same as status_id
57
+
58
+ * user.status= => #same as status_id =
59
+
60
+ * user.status_key => :locked #enum key
61
+
62
+ * user.status_name => '正常' #enum's human name
63
+
64
+ * user.status_is?(:normal) => true
65
+ * params: array, symbol, integer, string or array
66
+
67
+ * user.status_default_value => #default value , assign by :default option, default is the first of :enums
68
+
69
+ * user.set_status_value(:locked) #set value, same as user.status=2 or user.status_id=2
70
+ * params: array, symbol, integer, string or array
71
+
72
+ * user.update_status_value(:locked) #update value
73
+ * params: array, symbol, integer, string or array
74
+
75
+ ==named scope
76
+
77
+ * User.status_in(:locked)
78
+ * params: array, symbol, integer, string or array
79
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+
5
+ task :default => [:test]
6
+
7
+ desc 'Test the simple_enum plugin.'
8
+ Rake::TestTask.new(:test) do |t|
9
+ t.libs << 'lib'
10
+ t.pattern = 'test/*_test.rb'
11
+ t.verbose = true
12
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleEnum
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,128 @@
1
+ module SimpleEnum
2
+ def self.included(base)
3
+ base.cattr_accessor :enum_columns
4
+ base.extend EnumMethods
5
+ base.send :include, InstanceMethods
6
+ base.alias_method_chain :initialize, :enum_defaults
7
+ end
8
+
9
+ module EnumMethods
10
+ def has_enum(name, options)
11
+ column_attr = "enum_#{name}_column"
12
+ enums_attr = "#{name}_enums"
13
+ default_attr = "default_#{name}_enum"
14
+ cattr_accessor column_attr, enums_attr, default_attr
15
+ self.enum_columns ||= []
16
+ self.enum_columns << name
17
+ self.send("#{column_attr}=", options[:column] || "#{name}_id")
18
+ self.send("#{enums_attr}=", options[:enums])
19
+ self.send("#{default_attr}=", options[:default] || options[:enums].first.first)
20
+ self.module_eval do
21
+ scope "#{name}_in", lambda{|s| where(self.send(column_attr).to_sym => self.send("#{name}_value", s)) }
22
+
23
+ #类方法
24
+ #enum_in的别名:enum_is
25
+ self.class.send(:define_method, "#{name}_is") do |s|
26
+ self.send "#{name}_in", s
27
+ end
28
+
29
+ #返回一个select options数组
30
+ self.class.send(:define_method, "options_for_#{name}") do |*params|
31
+ if params.blank?
32
+ self.send(enums_attr).map{|s|[s.last, s.second]}
33
+ elsif params.first.is_a?(Symbol)
34
+ self.send(enums_attr).select{|e|params.include?(e.first)}.map{|s|[s.last, s.second]}
35
+ elsif params.first.is_a?(Array)
36
+ params.map{|p|[p.second, self.send(enums_attr).detect{|e|e.first == p.first}.try(:second)]}
37
+ end
38
+ end
39
+
40
+ #根据数组、符号、字符串返回value
41
+ self.class.send(:define_method, "#{name}_value") do |param|
42
+ if param.is_a?(Array)
43
+ param.map{|p|self.send("#{name}_value",p)}
44
+ elsif param.is_a?(Symbol)
45
+ self.send(enums_attr).assoc(param).try(:second)
46
+ elsif param.is_a?(String)
47
+ self.send(enums_attr).detect{|s| s.third == param }.try(:second)
48
+ else
49
+ param
50
+ end
51
+ end
52
+
53
+ #根据符号、字符串返回名称
54
+ self.class.send(:define_method, "#{name}_name") do |param|
55
+ self.send(enums_attr)
56
+ if param.is_a?(Symbol)
57
+ self.send(enums_attr).detect{|s| s.first == param }.try(:last)
58
+ elsif param.is_a?(String)
59
+ param
60
+ else
61
+ self.send(enums_attr).detect{|s| s.second == param }.try(:last)
62
+ end
63
+ end
64
+
65
+ #当前名称
66
+ self.send(:define_method, "#{name}_name") do
67
+ self.class.send(enums_attr).detect {|s| s.second == self.send(self.send(column_attr))}.try(:last)
68
+ end
69
+
70
+ #当前key
71
+ self.send(:define_method, "#{name}_key") do
72
+ self.class.send(enums_attr).detect {|s| s.second == self.send(self.send(column_attr))}.try(:first)
73
+ end
74
+
75
+ #设置值
76
+ self.send(:define_method, "set_#{name}_value") do |param|
77
+ value_id =
78
+ if param.is_a?(Symbol) #key
79
+ self.class.send("#{name}_value", param)
80
+ elsif param.is_a?(String) #name
81
+ self.send(enums_attr).detect {|s| s.last == param }.try(:second)
82
+ else #id
83
+ param
84
+ end
85
+ self.send("#{self.send(column_attr)}=", value_id)
86
+ value_id
87
+ end
88
+
89
+ #更新值
90
+ self.send(:define_method, "update_#{name}_value") do |param|
91
+ self.send("set_#{name}_value", param)
92
+ self.save(:validate => false)
93
+ end
94
+
95
+ #判断当前实例是否是
96
+ self.send(:define_method, "#{name}_is?") do |key|
97
+ if key.is_a?(Array)
98
+ key.detect{|p|self.send("#{name}_is?", p)}
99
+ else
100
+ self.class.send("#{name}_value", key) == self.send(self.send(column_attr))
101
+ end
102
+ end
103
+
104
+ #默认值
105
+ self.send(:define_method, "set_#{name}_default_value") do
106
+ self.send("#{self.send(column_attr)}=", self.send("#{name}_default_value"))
107
+ end
108
+
109
+ self.send(:define_method, "#{name}_default_value") do
110
+ self.class.send("#{name}_value", self.send(default_attr))
111
+ end
112
+
113
+ #可使用name和column访问
114
+ alias_attribute name, self.send(column_attr) unless name.to_s == self.send(column_attr).to_s
115
+ end
116
+ end
117
+ end
118
+
119
+ module InstanceMethods
120
+ def initialize_with_enum_defaults(attrs = nil, *args, &block)
121
+ initialize_without_enum_defaults(attrs, *args, &block)
122
+ self.enum_columns.each do |column|
123
+ self.send("set_#{column}_default_value") unless attrs && self.respond_to?("enum_#{column}_column") && attrs.include?(self.send("enum_#{column}_column").to_sym) || !self.respond_to?("set_#{column}_default_value")
124
+ end
125
+ yield(self) if block_given?
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "simple_enum/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "simple_enums"
7
+ s.version = SimpleEnum::VERSION
8
+ s.authors = ["CarylWang"]
9
+ s.email = ["xianwei.wang@gmail.com"]
10
+ s.homepage = "http://github.com/caryl/simple_enum"
11
+ s.summary = %q{a plugin for using enum attribute.}
12
+ s.description = %q{Simple Enum is a simple and useful plugin for using enum attribute.}
13
+
14
+ #s.rubyforge_project = "simple_enum"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
data/test/database.yml ADDED
@@ -0,0 +1,3 @@
1
+ plugin_test:
2
+ adapter: sqlite3
3
+ database: ":memory:"
data/test/schema.rb ADDED
@@ -0,0 +1,6 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :mocks, :force => true do |t|
3
+ t.string :name
4
+ t.integer :status
5
+ end
6
+ end
@@ -0,0 +1,159 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class SimpleEnumTest < Test::Unit::TestCase
4
+ def setup
5
+ @mock = Mock.new
6
+ end
7
+
8
+ def test_mock_new
9
+ mock = Mock.new(:name => "my name", :status => '3')
10
+ assert_equal mock.name, "my name"
11
+ assert_equal mock.status, 3
12
+ mock = Mock.new(:name => "my name")
13
+ assert_equal mock.name, "my name"
14
+ assert_equal mock.status, 2
15
+ end
16
+
17
+ def test_enum_scope
18
+ assert_equal Mock.status_in(:normal).class, ActiveRecord::Relation
19
+ assert_equal Mock.kind_in(:normal).class, ActiveRecord::Relation
20
+ assert_equal Mock.status_is(:normal).class, ActiveRecord::Relation
21
+ end
22
+
23
+ def test_enum_enums
24
+ assert_equal Mock.status_enums, [[:normal, 1, '正常'],[:locked, 2, '锁定'],[:deleted, 3, '已删除']]
25
+ assert_equal Mock.kind_enums, [[:admin, 1, '管理员'],[:member, 2, '成员']]
26
+ end
27
+
28
+ def test_options_for_enum
29
+ assert_equal Mock.options_for_status, [['正常',1],['锁定',2],['已删除',3]]
30
+ assert_equal Mock.options_for_status(:normal, :locked), [['正常',1],['锁定',2]]
31
+ assert_equal Mock.options_for_status([:normal, '审核'], [:locked, '锁定']), [['审核',1],['锁定',2]]
32
+ assert_equal Mock.options_for_kind, [['管理员',1],['成员',2]]
33
+ end
34
+
35
+ def test_enum_value
36
+ assert_equal Mock.status_value(:locked), 2
37
+ assert_equal Mock.status_value('正常'), 1
38
+ assert_equal Mock.status_value(['正常', :deleted]), [1,3]
39
+ assert_equal Mock.status_value(:other), nil
40
+
41
+ assert_equal Mock.kind_value(:admin), 1
42
+ assert_equal Mock.kind_value('成员'), 2
43
+ assert_equal Mock.kind_value(['成员', :admin]), [2,1]
44
+ assert_equal Mock.kind_value(:other), nil
45
+ end
46
+
47
+ def test_class_enum_name
48
+ assert_equal Mock.status_name(:locked), '锁定'
49
+ assert_equal Mock.status_name('正常'), '正常'
50
+ assert_equal Mock.status_name(1), '正常'
51
+ assert_equal Mock.status_name(:other), nil
52
+
53
+ assert_equal Mock.kind_name(:admin), '管理员'
54
+ assert_equal Mock.kind_name('成员'), '成员'
55
+ assert_equal Mock.kind_name(1), '管理员'
56
+ assert_equal Mock.kind_name(:other), nil
57
+ end
58
+
59
+ def test_enum_default
60
+ mock = Mock.new
61
+ assert_equal mock.status, 2
62
+ mock.status = 3
63
+ assert_equal mock.status, 3
64
+ assert_equal mock.status_default_value, 2
65
+
66
+ mock = Mock.new
67
+ assert_equal mock.kind, 1
68
+ assert_equal mock.kind_id, 1
69
+ mock.kind = 2
70
+ assert_equal mock.kind, 2
71
+ assert_equal mock.kind_id, 2
72
+ assert_equal mock.kind_default_value, 1
73
+ end
74
+
75
+ def test_enum_key
76
+ @mock.set_status_value(:locked)
77
+ assert_equal @mock.status_key, :locked
78
+ @mock.status = 1
79
+ assert_equal @mock.status_key, :normal
80
+
81
+ @mock.set_kind_value(:admin)
82
+ assert_equal @mock.kind_key, :admin
83
+ @mock.kind = 2
84
+ assert_equal @mock.kind_key, :member
85
+ end
86
+
87
+ def test_enum_name
88
+ @mock.set_status_value(:locked)
89
+ assert_equal @mock.status_name, '锁定'
90
+ @mock.status = 1
91
+ assert_equal @mock.status_name, '正常'
92
+
93
+ @mock.set_kind_value(:admin)
94
+ assert_equal @mock.kind_name, '管理员'
95
+ @mock.kind_id = 2
96
+ assert_equal @mock.kind_name, '成员'
97
+ end
98
+
99
+ def test_enum_is?
100
+ @mock.set_status_value(:locked)
101
+ assert @mock.status_is?(:locked)
102
+ assert @mock.status_is?(2)
103
+ assert @mock.status_is?('锁定')
104
+ assert !@mock.status_is?('其他')
105
+
106
+ @mock.set_kind_value(:admin)
107
+ assert @mock.kind_is?(:admin)
108
+ assert @mock.kind_is?(1)
109
+ assert @mock.kind_is?('管理员')
110
+ assert !@mock.kind_is?(:member)
111
+ end
112
+
113
+ def test_set_enum_value
114
+ @mock.set_status_value(:normal)
115
+ assert @mock.status_is?(:normal)
116
+
117
+ @mock.set_kind_value(:member)
118
+ assert @mock.kind_is?(:member)
119
+ end
120
+
121
+ def test_update_enum_value
122
+ @mock.update_status_value(:normal)
123
+ @mock.reload
124
+ assert @mock.status_is?(:normal)
125
+ end
126
+
127
+ def test_set_default_value
128
+ mock = Mock.new
129
+ mock.status = 1
130
+ mock.set_status_default_value
131
+ assert mock.status_is?(:locked)
132
+
133
+ mock.kind_id = 2
134
+ assert mock.kind_is?(:member)
135
+ mock.set_kind_default_value
136
+ assert mock.kind_is?(:admin)
137
+ end
138
+
139
+ def test_enum_on_save
140
+ mock = Mock.new
141
+ mock.save
142
+ assert mock.status_is?(:locked)
143
+ assert mock.kind_is?(:admin)
144
+
145
+ mock.set_status_value(:normal)
146
+ mock.set_kind_value(:member)
147
+ mock.save
148
+ assert mock.status_is?(:normal)
149
+ assert mock.kind_is?(:member)
150
+ end
151
+ end
152
+
153
+
154
+ class Mock < ActiveRecord::Base
155
+ attr_accessor :kind_id
156
+ include SimpleEnum
157
+ has_enum :status, :enums => [[:normal, 1, '正常'],[:locked, 2, '锁定'],[:deleted, 3, '已删除']], :column => :status, :default => :locked
158
+ has_enum :kind, :enums => [[:admin, 1, '管理员'],[:member, 2, '成员']], :column => :kind_id
159
+ end
@@ -0,0 +1,11 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+
3
+ require 'rubygems'
4
+ require 'test/unit'
5
+ require 'active_record'
6
+ require 'simple_enum'
7
+
8
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
9
+ ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'plugin_test'])
10
+
11
+ load(File.dirname(__FILE__) + "/schema.rb") if File.exist?(File.dirname(__FILE__) + "/schema.rb")
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_enums
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - CarylWang
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-03-27 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: Simple Enum is a simple and useful plugin for using enum attribute.
22
+ email:
23
+ - xianwei.wang@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - Gemfile
32
+ - README.rdoc
33
+ - Rakefile
34
+ - lib/simple_enum.rb
35
+ - lib/simple_enum/version.rb
36
+ - simple_enum.gemspec
37
+ - test/database.yml
38
+ - test/schema.rb
39
+ - test/simple_enum_test.rb
40
+ - test/test_helper.rb
41
+ homepage: http://github.com/caryl/simple_enum
42
+ licenses: []
43
+
44
+ post_install_message:
45
+ rdoc_options: []
46
+
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ hash: 3
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.8.10
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: a plugin for using enum attribute.
74
+ test_files: []
75
+