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 +4 -0
- data/README.rdoc +79 -0
- data/Rakefile +12 -0
- data/lib/simple_enum/version.rb +3 -0
- data/lib/simple_enum.rb +128 -0
- data/simple_enum.gemspec +24 -0
- data/test/database.yml +3 -0
- data/test/schema.rb +6 -0
- data/test/simple_enum_test.rb +159 -0
- data/test/test_helper.rb +11 -0
- metadata +75 -0
data/Gemfile
ADDED
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
data/lib/simple_enum.rb
ADDED
@@ -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
|
data/simple_enum.gemspec
ADDED
@@ -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
data/test/schema.rb
ADDED
@@ -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
|
data/test/test_helper.rb
ADDED
@@ -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
|
+
|