selectable_attr 0.3.7

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/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ /*.gem
2
+ /coverage
3
+ /pkg
4
+ /rdoc
5
+ /selectable_attr_test.sqlite3.db
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Takeshi AKIMA
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,334 @@
1
+ = SelectableAttr
2
+ == Introduction
3
+ selectable_attr は、コードが割り振られるような特定の属性について*コード*、*プログラム上での名前*、
4
+ *表示するための名前*などをまとめて管理するものです。
5
+ http://github.com/akm/selectable_attr/tree/master
6
+
7
+ Railsで使用する場合、selectable_attr_railsと一緒に使うことをオススメします。
8
+ http://github.com/akm/selectable_attr_rails/tree/master
9
+
10
+
11
+ == Install
12
+ === 1. Railsプロジェクトで使う場合
13
+ ==== a. plugin install
14
+ ruby script/plugin install git://github.com/akm/selectable_attr.git
15
+ ruby script/plugin install git://github.com/akm/selectable_attr_rails.git
16
+
17
+ ==== b. gem install
18
+ [sudo] gem install akimatter-selectable_attr akimatter-selectable_attr_rails -s http://gems.github .com
19
+
20
+ === 2. 非Railsで使う場合
21
+ ==== a. gem install
22
+ [sudo] gem install akimatter-selectable_attr -s http://gems.github .com
23
+
24
+
25
+
26
+ == Tutorial
27
+
28
+ === シンプルなパターン
29
+ require 'rubygems'
30
+ require 'selectable_attr'
31
+
32
+ class Person
33
+ include ::SelectableAttr::Base
34
+
35
+ selectable_attr :gender do
36
+ entry '1', :male, '男性'
37
+ entry '2', :female, '女性'
38
+ entry '9', :other, 'その他'
39
+ end
40
+ end
41
+
42
+ 上記のようなクラスがあった場合、以下のようなクラスメソッドを使うことが可能です。
43
+
44
+ irb(main):020:0> Person.gender_ids
45
+ => ["1", "2", "9"]
46
+ irb(main):021:0> Person.gender_keys
47
+ => [:male, :female, :other]
48
+ irb(main):022:0> Person.gender_names
49
+ => ["男性", "女性", "その他"]
50
+ irb(main):023:0> Person.gender_options
51
+ => [["男性", "1"], ["女性", "2"], ["その他", "9"]] # railsでoptions_for_selectメソッドなどに使えます。
52
+ irb(main):024:0> Person.gender_key_by_id("1")
53
+ => :male
54
+ irb(main):025:0> Person.gender_name_by_id("1")
55
+ => "男性"
56
+ irb(main):026:0> Person.gender_id_by_key(:male) # 特定のキーから対応するidを取得できます。
57
+ => "1"
58
+ irb(main):027:0> Person.gender_name_by_key(:male)
59
+ => "男性"
60
+
61
+ また使用可能なインスタンスメソッドには以下のようなものがあります。
62
+
63
+ irb> person = Person.new
64
+ => #<Person:0x133b9d0>
65
+ irb> person.gender_key
66
+ => nil
67
+ irb> person.gender_name
68
+ => nil
69
+ irb> person.gender = "2"
70
+ => "2"
71
+ irb> person.gender_key
72
+ => :female
73
+ irb> person.gender_name
74
+ => "女性"
75
+ irb> person.gender_key = :other
76
+ => :other
77
+ irb> person.gender
78
+ => "9"
79
+ irb> person.gender_name
80
+ => "その他"
81
+
82
+ genderが代入可能なことはもちろん、gender_keyも代入可能です。
83
+ # ただし、gender_nameには代入できません。
84
+
85
+
86
+ === 複数の値を取りうるパターン
87
+ require 'rubygems'
88
+ require 'selectable_attr'
89
+
90
+ class RoomSearch
91
+ include ::SelectableAttr::Base
92
+
93
+ multi_selectable_attr :room_type do
94
+ entry '01', :single, 'シングル'
95
+ entry '02', :twin, 'ツイン'
96
+ entry '03', :double, 'ダブル'
97
+ entry '04', :triple, 'トリプル'
98
+ end
99
+ end
100
+
101
+ multi_selectable_attrを使った場合に使用できるクラスメソッドは、selectable_attrの場合と同じです。
102
+
103
+ irb> room_search = RoomSearch.new
104
+ => #<RoomSearch:0x134a070>
105
+ irb> room_search.room_type_ids
106
+ => []
107
+ irb> room_search.room_type_keys
108
+ => []
109
+ irb> room_search.room_type_names
110
+ => []
111
+ irb> room_search.room_type_selection
112
+ => [false, false, false, false]
113
+ irb> room_search.room_type_keys = [:twin, :double]
114
+ => [:twin, :double]
115
+ irb> room_search.room_type
116
+ => ["02", "03"]
117
+ irb> room_search.room_type_names
118
+ => ["ツイン", "ダブル"]
119
+ irb> room_search.room_type_ids
120
+ => ["02", "03"]
121
+ irb> room_search.room_type = ["01", "04"]
122
+ => ["01", "04"]
123
+ irb> room_search.room_type_keys
124
+ => [:single, :triple]
125
+ irb> room_search.room_type_names
126
+ => ["シングル", "トリプル"]
127
+ irb> room_search.room_type_selection
128
+ => [true, false, false, true]
129
+ irb> room_search.room_type_hash_array
130
+ => [{:select=>true, :key=>:single, :name=>"シングル", :id=>"01"}, {:select=>false, :key=>:twin, :name=>"ツイン", :id=>"02"}, {:select=>false, :key=>:double, :name=>"ダブル", :id=>"03"}, {:select=>true, :key=>:triple, :name=>"トリプル", :id=>"04"}]
131
+ irb> room_search.room_type_hash_array_selected
132
+ => [{:select=>true, :key=>:single, :name=>"シングル", :id=>"01"}, {:select=>true, :key=>:triple, :name=>"トリプル", :id=>"04"}]
133
+
134
+
135
+
136
+ === Entry
137
+ ==== エントリの取得
138
+ エントリは様々な拡張が可能です。例えば以下のようにid、key、name以外の属性を設定することも可能です。
139
+
140
+ require 'rubygems'
141
+ require 'selectable_attr'
142
+
143
+ class Site
144
+ include ::SelectableAttr::Base
145
+
146
+ selectable_attr :protocol do
147
+ entry '01', :http , 'HTTP' , :port => 80
148
+ entry '02', :https, 'HTTPS' , :port => 443
149
+ entry '03', :ssh , 'SSH' , :port => 22
150
+ entry '04', :svn , 'Subversion', :port => 3690
151
+ end
152
+ end
153
+
154
+ クラスメソッドで各エントリを取得することが可能です。
155
+ entry = Site.protocol_entry_by_key(:https)
156
+ entry = Site.protocol_entry_by_id('02')
157
+
158
+ インスタンスメソッドでは以下のように取得できます。
159
+ site = Site.new
160
+ site.protocol_key = :https
161
+ entry = site.protocol_entry
162
+
163
+ ==== エントリの属性
164
+ id, key, nameもそのままメソッドとして用意されています。
165
+ irb> entry.id
166
+ => "02"
167
+ irb> entry.key
168
+ => :https
169
+ irb> entry.name
170
+ => "HTTPS"
171
+
172
+ またオプションの属性もHashのようにアクセス可能です。
173
+ irb> entry[:port]
174
+ => 443
175
+
176
+ to_hashメソッドで、id, key, nameを含むHashを作成します。
177
+ irb> entry.to_hash
178
+ => {:key=>:https, :port=>443, :name=>"HTTPS", :id=>"02"}
179
+
180
+ matchメソッドでid,key,nameを除くオプションの属性群と一致しているかどうかを判断可能です。
181
+
182
+ irb> entry.match?(:port => 22)
183
+ => false
184
+ irb> entry.match?(:port => 443)
185
+ => true
186
+
187
+ # ここではオプションの属性として:portしか設定していないので、matchに渡すHashのキーと値の組み合わせも一つだけですが、
188
+ # 複数ある場合にmatch?がtrueとなるためには、完全に一致している必要があります。
189
+
190
+
191
+ ==== クラスメソッドでのエントリの扱い
192
+ クラスメソッドでエントリを取得する方法として、xxx_entry_by_id, xxx_entry_by_keyを紹介しましたが、
193
+ 全てのエントリで構成される配列を取得するメソッドが xxx_entriesです。
194
+
195
+ irb> entries = Site.protocol_entries
196
+ irb> entries.length
197
+ => 4
198
+
199
+ また、各エントリをto_hashでHashに変換した配列を xxx_hash_arrayメソッドで取得することも可能です。
200
+ irb> Site.protocol_hash_array
201
+ => [
202
+ {:key=>:http, :port=>80, :name=>"HTTP", :id=>"01"},
203
+ {:key=>:https, :port=>443, :name=>"HTTPS", :id=>"02"},
204
+ {:key=>:ssh, :port=>22, :name=>"SSH", :id=>"03"},
205
+ {:key=>:svn, :port=>3690, :name=>"Subversion", :id=>"04"}
206
+ ]
207
+
208
+
209
+ === Enum
210
+ あまり表にでてきませんが、エントリをまとめる役割のオブジェクトがEnumです。
211
+ これはクラスメソッドxxx_enumで取得することができます。
212
+
213
+ irb> enum = Site.protocol_enum
214
+
215
+ Enumには以下のようなメソッドが用意されています。
216
+ irb> enum.entries
217
+ irb> enum.entries.map{|entry| entry[:port]}
218
+ => [80, 443, 22, 3690]
219
+
220
+ EnumはEnumerableをincludeしているため、以下のように記述することも可能です。
221
+ irb> enum.map{|entry| entry[:port]}
222
+ => [80, 443, 22, 3690]
223
+
224
+ irb> enum.entry_by_id("03")
225
+ => #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
226
+ irb> enum.entry_by_key(:ssh)
227
+ => #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
228
+ irb> enum.entry_by_id_or_key(:ssh)
229
+ => #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
230
+ irb> enum.entry_by_id_or_key('03')
231
+ => #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
232
+ irb> enum.entry_by_hash(:port => 22)
233
+ => #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
234
+
235
+ また、これらのメソッドが面倒と感じるようであれば、以下のような簡単なアクセスも可能です。
236
+ irb> enum['03']
237
+ => #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
238
+ irb> enum[:ssh]
239
+ => #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
240
+ irb> enum[:port => 22]
241
+ => #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
242
+
243
+ またクラスメソッドで紹介したようなxxx_ids, xxx_keys, xxx_namesや、xxx_key_by_idなどのメソッドも用意されています。
244
+ irb> enum.ids
245
+ => ["01", "02", "03", "04"]
246
+ irb> enum.keys
247
+ => [:http, :https, :ssh, :svn]
248
+ irb> enum.names
249
+ => ["HTTP", "HTTPS", "SSH", "Subversion"]
250
+ irb> enum.options
251
+ => [["HTTP", "01"], ["HTTPS", "02"], ["SSH", "03"], ["Subversion", "04"]]
252
+ irb> enum.key_by_id('04')
253
+ => :svn
254
+ irb> enum.id_by_key(:svn)
255
+ => "04"
256
+ irb> enum.name_by_id('04')
257
+ => "Subversion"
258
+ irb> enum.name_by_key(:svn)
259
+ => "Subversion"
260
+ irb> enum.to_hash_array
261
+ => [
262
+ {:key=>:http, :port=>80, :name=>"HTTP", :id=>"01"},
263
+ {:key=>:https, :port=>443, :name=>"HTTPS", :id=>"02"},
264
+ {:key=>:ssh, :port=>22, :name=>"SSH", :id=>"03"},
265
+ {:key=>:svn, :port=>3690, :name=>"Subversion", :id=>"04"}
266
+ ]
267
+
268
+ id, key以外でエントリを特定したい場合はfindメソッドが使えます。
269
+ irb> enum.find(:port => 22)
270
+ => #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
271
+
272
+ findメソッドにはブロックを渡すこともできます。
273
+ irb> enum.find{|entry| entry[:port] > 1024}
274
+ => #<SelectableAttr::Enum::Entry:1352a04 @id="04", @key=:svn, @name="Subversion", @options={:port=>3690}
275
+
276
+
277
+ === Entryへのメソッド定義
278
+ entryメソッドにブロックを渡すとエントリのオブジェクトにメソッドを定義することが可能です。
279
+
280
+ require 'rubygems'
281
+ require 'selectable_attr'
282
+
283
+ class Site
284
+ include ::SelectableAttr::Base
285
+
286
+ selectable_attr :protocol do
287
+ entry '01', :http , 'HTTP', :port => 80 do
288
+ def accept?(model)
289
+ # httpで指定された場合はhttpsも可、という仕様
290
+ model.url =~ /^http[s]{0,1}\:\/\//
291
+ end
292
+ end
293
+
294
+ entry '02', :https, 'HTTPS', :port => 443 do
295
+ def accept?(model)
296
+ model.url =~ /^https\:\/\//
297
+ end
298
+ end
299
+
300
+ entry '03', :ssh , 'SSH', :port => 22 do
301
+ def accept?(model)
302
+ false
303
+ end
304
+ end
305
+
306
+ entry '04', :svn , 'Subversion', :port => 3690 do
307
+ def accept?(model)
308
+ model.url =~ /^svn\:\/\/|^svn+ssh\:\/\//
309
+ end
310
+ end
311
+
312
+ end
313
+ end
314
+
315
+ enum = Site.protocol_enum
316
+
317
+ class Project
318
+ attr_accessor :url
319
+ end
320
+ project = Project.new
321
+ project.url = "http://github.com/akm/selectable_attr/tree/master"
322
+
323
+ irb> enum[:http].accept?(project)
324
+ => 0
325
+ irb> enum[:https].accept?(project)
326
+ => nil
327
+
328
+ というようにentryメソッドに渡したブロックは、生成されるエントリオブジェクトのコンテキストでinstance_evalされるので、そのメソッドを定義することが可能です。
329
+
330
+
331
+
332
+
333
+ == Credit
334
+ Copyright (c) 2008 Takeshi AKIMA, released under the MIT lice nse
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ gem 'rspec', '>= 1.1.4'
3
+ require 'rake'
4
+ require 'rake/rdoctask'
5
+ require 'spec/rake/spectask'
6
+ require 'spec/rake/verify_rcov'
7
+
8
+ desc 'Default: run unit tests.'
9
+ task :default => :spec
10
+
11
+ task :pre_commit => [:spec, 'coverage:verify']
12
+
13
+ desc 'Run all specs under spec/**/*_spec.rb'
14
+ Spec::Rake::SpecTask.new(:spec => 'coverage:clean') do |t|
15
+ t.spec_files = FileList['spec/**/*_spec.rb']
16
+ t.spec_opts = ["-c", "--diff"]
17
+ t.rcov = true
18
+ t.rcov_opts = ["--include-file", "lib\/*\.rb", "--exclude", "spec\/"]
19
+ end
20
+
21
+ desc 'Generate documentation for the selectable_attr plugin.'
22
+ Rake::RDocTask.new(:rdoc) do |rdoc|
23
+ rdoc.rdoc_dir = 'rdoc'
24
+ rdoc.title = 'SelectableAttr'
25
+ rdoc.options << '--line-numbers' << '--inline-source' << '-c UTF-8'
26
+ rdoc.rdoc_files.include('README*')
27
+ rdoc.rdoc_files.include('lib/**/*.rb')
28
+ end
29
+
30
+ namespace :coverage do
31
+ desc "Delete aggregate coverage data."
32
+ task(:clean) { rm_f "coverage" }
33
+
34
+ desc "verify coverage threshold via RCov"
35
+ RCov::VerifyTask.new(:verify => :spec) do |t|
36
+ t.threshold = 100.0 # Make sure you have rcov 0.7 or higher!
37
+ t.index_html = 'coverage/index.html'
38
+ end
39
+ end
40
+
41
+ begin
42
+ require 'jeweler'
43
+ Jeweler::Tasks.new do |s|
44
+ s.name = "selectable_attr"
45
+ s.summary = "selectable_attr generates extra methods dynamically"
46
+ s.description = "selectable_attr generates extra methods dynamically for attribute which has options"
47
+ s.email = "akima@gmail.com"
48
+ s.homepage = "http://github.com/akm/selectable_attr/"
49
+ s.authors = ["Takeshi Akima"]
50
+ end
51
+ rescue LoadError
52
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
53
+ end
54
+
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 7
3
+ :major: 0
4
+ :minor: 3
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'selectable_attr'
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here