code-box 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +62 -17
- data/lib/code-box/acts_as_code.rb +2 -2
- data/lib/code-box/code_attribute.rb +57 -7
- data/lib/code-box/version.rb +1 -1
- data/test/code-box/test_acts_as_code.rb +3 -3
- data/test/code-box/test_code_attribute.rb +27 -4
- data/test/resources/locale/de.yml +7 -1
- data/test/resources/locale/en.yml +7 -1
- data/test/resources/models.rb +10 -1
- metadata +2 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
-
#
|
1
|
+
# CodeBox::CodeAttribute
|
2
|
+
|
3
|
+
Lets you define attributes as codes, instead keys (ids). For simple option storage saving a string code is often more simple an conveniant the storing an artificial id-key referencing a special code object.
|
4
|
+
CodeBox lets you access define codes as strings and access the associated code objects in various ways.
|
5
|
+
|
2
6
|
|
3
|
-
TODO: Write a gem description
|
4
7
|
|
5
8
|
## Installation
|
6
9
|
|
@@ -16,7 +19,9 @@ Or install it yourself as:
|
|
16
19
|
|
17
20
|
$ gem install code-box
|
18
21
|
|
19
|
-
|
22
|
+
|
23
|
+
|
24
|
+
## Sample Usages
|
20
25
|
|
21
26
|
### Specifying attributes as codes
|
22
27
|
|
@@ -24,9 +29,10 @@ There are cases you want to store 'named codes' instead artificial keys.
|
|
24
29
|
Codes make sense for stable references and better readability of the raw data.
|
25
30
|
|
26
31
|
There are several options to specify an attribute as a code:
|
27
|
-
1.
|
28
|
-
1.
|
29
|
-
1.
|
32
|
+
1. The code value is used for I18n translation (e.g. nationality_code: 'SUI' -> nationality: 'Switzerland' (when locale is 'en')).
|
33
|
+
1. The code value is used to lookup a specific code object that implements `.for_code`.
|
34
|
+
1. The code value is a foreign key on a specific ActiveRecord code object.
|
35
|
+
|
30
36
|
|
31
37
|
#### Lookup through I18n
|
32
38
|
|
@@ -35,13 +41,14 @@ Example
|
|
35
41
|
class Person
|
36
42
|
iclude CodeBox::CodeAttribute
|
37
43
|
|
38
|
-
attr_accessor
|
39
|
-
end
|
44
|
+
attr_accessor :nationality_code
|
40
45
|
|
41
|
-
|
46
|
+
code_attribute :nationality
|
47
|
+
end
|
42
48
|
|
43
|
-
|
49
|
+
The include will create the following method in Person:
|
44
50
|
|
51
|
+
`#nationality` Will return the nationality text for the value stored in `nationality_code`. For the code 'SUI' the I18n key would look like: `activerecord.values.person.nationality_code.SUI` (Note: The key is build like the standard I18n keys for activerecord classes or attribute by default. Since I dislike the `activerecord` naming and prefer `model` I made this configurable - see below).
|
45
52
|
|
46
53
|
|
47
54
|
#### Lookup through code object
|
@@ -51,29 +58,67 @@ Example
|
|
51
58
|
class Person
|
52
59
|
iclude CodeBox::CodeAttribute
|
53
60
|
|
54
|
-
attr_accessor :nationality_code
|
61
|
+
attr_accessor :nationality_code
|
62
|
+
|
63
|
+
code_attribute :nationality, :lookup_type => :lookup
|
55
64
|
end
|
56
65
|
|
57
66
|
class Code::Nationality
|
58
67
|
attr_accessor :code, :name
|
59
68
|
|
60
|
-
def
|
61
|
-
return the correct Code::Nationality for the passed code
|
69
|
+
def self.for_code(code)
|
70
|
+
# return the correct Code::Nationality for the passed code
|
62
71
|
end
|
63
72
|
end
|
64
73
|
|
65
|
-
The include will create the following methods in Person:
|
66
74
|
|
67
|
-
|
75
|
+
The include will create the following method in Person:
|
76
|
+
|
77
|
+
`#nationality` Will return the nationality object looked up using the method '.for_code' on the code class.
|
78
|
+
Translation then can be done within this class with the first method described above.
|
79
|
+
|
68
80
|
|
69
81
|
|
70
82
|
#### Lookup through associated AR Code Object
|
71
|
-
|
83
|
+
|
84
|
+
The code value is interpreted as a foreign key on an associated AR Code object.
|
85
|
+
|
86
|
+
class Person < ActiveRecord::Base
|
87
|
+
iclude CodeBox::CodeAttribute
|
88
|
+
|
89
|
+
code_attribute :nationality, :lookup_type => :activerecord
|
90
|
+
end
|
91
|
+
|
92
|
+
class Code::Nationality < ActiveRecord::Base
|
93
|
+
# has attribute 'code' of type string
|
94
|
+
end
|
95
|
+
|
96
|
+
The include and code specification will create the following methods in Person:
|
97
|
+
|
98
|
+
`#nationality` - will return the nationality looked up through AR association on the associated code object - implemented through below AR association:
|
99
|
+
|
100
|
+
belongs_to :nationality,
|
101
|
+
:class_name => 'Codes::Nationality',
|
102
|
+
:foreign_key => :nationality_code,
|
103
|
+
:primary_key => :code
|
104
|
+
|
105
|
+
|
106
|
+
## Configuration details
|
107
|
+
|
108
|
+
### Lookup through I18n
|
109
|
+
... to be completed
|
110
|
+
|
111
|
+
### Lookup through code object
|
112
|
+
... to be completed
|
113
|
+
|
114
|
+
### Lookup through associated AR Code Object
|
115
|
+
... to be completed
|
116
|
+
|
72
117
|
|
73
118
|
|
74
119
|
## Contributing
|
75
120
|
|
76
|
-
1. Fork it
|
121
|
+
1. Fork it!
|
77
122
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
78
123
|
3. Commit your changes (`git commit -am 'Added some feature'`)
|
79
124
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -59,7 +59,7 @@ module CodeBox
|
|
59
59
|
all.inject({}) {|hash, obj| hash[obj.#{code_attr}] = obj; hash }
|
60
60
|
end
|
61
61
|
|
62
|
-
def self.
|
62
|
+
def self.for_code(code)
|
63
63
|
code_cache[code]
|
64
64
|
end
|
65
65
|
|
@@ -92,7 +92,7 @@ module CodeBox
|
|
92
92
|
all.inject({}) {|hash, obj| hash[obj.#{code_attr}] = obj; hash }
|
93
93
|
end
|
94
94
|
|
95
|
-
def self.
|
95
|
+
def self.for_code(code)
|
96
96
|
code_cache[code]
|
97
97
|
end
|
98
98
|
|
@@ -3,9 +3,49 @@
|
|
3
3
|
module CodeBox
|
4
4
|
|
5
5
|
module CodeAttribute
|
6
|
+
Config = { :i18n_model_segment => :activerecord }
|
7
|
+
|
8
|
+
def i18n_model_segment=(segment)
|
9
|
+
Config[:i18n_model_segment] = segment
|
10
|
+
end
|
11
|
+
def i18n_model_segment
|
12
|
+
Config[:i18n_model_segment]
|
13
|
+
end
|
14
|
+
module_function :i18n_model_segment=, :i18n_model_segment
|
15
|
+
|
16
|
+
|
17
|
+
def self.[](*options)
|
18
|
+
instance_eval <<-RUBY_
|
19
|
+
class << self
|
20
|
+
def _code_box_i18n_model_segment
|
21
|
+
"#{options.extract_options![:i18n_model_segment]}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
RUBY_
|
25
|
+
self
|
26
|
+
end
|
6
27
|
|
7
28
|
def self.included(base)
|
29
|
+
unless (class << self; self; end).method_defined?(:_code_box_i18n_model_segment)
|
30
|
+
instance_eval <<-RUBY_
|
31
|
+
class << self
|
32
|
+
def _code_box_i18n_model_segment
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
RUBY_
|
37
|
+
end
|
38
|
+
|
8
39
|
base.extend(ClassMethods)
|
40
|
+
|
41
|
+
instance_eval <<-RUBY_
|
42
|
+
class << base
|
43
|
+
def _code_box_i18n_model_segment
|
44
|
+
return CodeBox::CodeAttribute.i18n_model_segment if "#{self._code_box_i18n_model_segment}".empty?
|
45
|
+
"#{self._code_box_i18n_model_segment}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
RUBY_
|
9
49
|
end
|
10
50
|
|
11
51
|
|
@@ -34,7 +74,7 @@ module CodeBox
|
|
34
74
|
class_eval <<-RUBY_
|
35
75
|
# getter
|
36
76
|
def #{code_name}
|
37
|
-
#{code_class_name}.
|
77
|
+
#{code_class_name}.for_code(#{code_attr_name})
|
38
78
|
end
|
39
79
|
|
40
80
|
# setter
|
@@ -57,7 +97,7 @@ module CodeBox
|
|
57
97
|
# getter
|
58
98
|
def #{code_name}(locale=I18n.locale)
|
59
99
|
code = self.#{code_attr_name}
|
60
|
-
self.class.translate_#{code_attr_name}(code, locale)
|
100
|
+
self.class.translate_#{code_attr_name}(code, :locale => locale)
|
61
101
|
end
|
62
102
|
|
63
103
|
# setter
|
@@ -67,13 +107,23 @@ module CodeBox
|
|
67
107
|
|
68
108
|
# translator
|
69
109
|
class << self
|
70
|
-
def translate_#{code_attr_name}(code
|
71
|
-
|
72
|
-
|
110
|
+
def translate_#{code_attr_name}(*code)
|
111
|
+
options = code.extract_options!
|
112
|
+
locale = options[:locale] || I18n.locale
|
113
|
+
codes = code.first
|
114
|
+
is_paramter_array = codes.kind_of? Array
|
115
|
+
|
116
|
+
codes = Array(codes)
|
117
|
+
translated_codes = codes.map { |code|
|
73
118
|
code_key = code.nil? ? :null_value : code
|
74
|
-
I18n.t("
|
119
|
+
I18n.t("\#{self._code_box_i18n_model_segment}.\#{self.name.underscore}.values.#{code_attr_name}.\#{code_key}", :locale => locale)
|
75
120
|
}
|
76
|
-
|
121
|
+
|
122
|
+
if options[:build] == :zip
|
123
|
+
translated_codes.zip(codes)
|
124
|
+
else
|
125
|
+
is_paramter_array ? translated_codes : translated_codes.first
|
126
|
+
end
|
77
127
|
end
|
78
128
|
end
|
79
129
|
RUBY_
|
data/lib/code-box/version.rb
CHANGED
@@ -12,8 +12,8 @@ class TestActsAsCode < Test::Unit::TestCase
|
|
12
12
|
def test_constants
|
13
13
|
assert_equal 2, Codes::CivilStatus::all.size
|
14
14
|
|
15
|
-
assert_equal Codes::CivilStatus.
|
16
|
-
assert_equal Codes::CivilStatus.
|
15
|
+
assert_equal Codes::CivilStatus.for_code('single'), Codes::CivilStatus::all.first
|
16
|
+
assert_equal Codes::CivilStatus.for_code('married'), Codes::CivilStatus::all.last
|
17
17
|
end
|
18
18
|
|
19
19
|
|
@@ -29,7 +29,7 @@ class TestActsAsCode < Test::Unit::TestCase
|
|
29
29
|
code_1 = Codes::ArCode.create(:code => 'code_1', :name => "Code_1_name")
|
30
30
|
code_2 = Codes::ArCode.create(:code => 'code_2', :name => "Code_2_name")
|
31
31
|
|
32
|
-
assert_equal code_2, Codes::ArCode.
|
32
|
+
assert_equal code_2, Codes::ArCode.for_code('code_2')
|
33
33
|
end
|
34
34
|
|
35
35
|
|
@@ -23,7 +23,15 @@ class TestCodeAttribute < Test::Unit::TestCase
|
|
23
23
|
|
24
24
|
assert_equal('de', obj.country_iso)
|
25
25
|
assert_equal('Deutschland', obj.country(:de))
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_code_attribute_i18n_lookup_w_segment
|
29
|
+
obj = Codes::SegmentModel.new
|
30
|
+
obj.gender_code = 'f'
|
31
|
+
I18n.locale =:en
|
26
32
|
|
33
|
+
assert_equal('f', obj.gender_code)
|
34
|
+
assert_equal('female', obj.gender)
|
27
35
|
end
|
28
36
|
|
29
37
|
def test_code_attribute_i18n_translator_with_single_code
|
@@ -31,7 +39,7 @@ class TestCodeAttribute < Test::Unit::TestCase
|
|
31
39
|
translation = Codes::SampleClass.translate_gender_code('f')
|
32
40
|
assert_equal('weiblich', translation)
|
33
41
|
|
34
|
-
translation = Codes::SampleClass.translate_gender_code('f', :en)
|
42
|
+
translation = Codes::SampleClass.translate_gender_code('f', :locale => :en)
|
35
43
|
assert_equal('female', translation)
|
36
44
|
end
|
37
45
|
|
@@ -43,18 +51,33 @@ class TestCodeAttribute < Test::Unit::TestCase
|
|
43
51
|
assert_equal('weiblich', translation.first)
|
44
52
|
assert_equal('männlich', translation.last)
|
45
53
|
|
46
|
-
translation = Codes::SampleClass.translate_gender_code(['f', 'm'], :en)
|
54
|
+
translation = Codes::SampleClass.translate_gender_code(['f', 'm'], :locale => :en)
|
47
55
|
|
48
56
|
assert translation.kind_of? Array
|
49
57
|
assert_equal('female', translation.first)
|
50
58
|
assert_equal('male', translation.last)
|
51
59
|
end
|
52
60
|
|
61
|
+
def test_code_attribute_i18n_translator_with_multiple_codes_zipped
|
62
|
+
I18n.locale = :de
|
63
|
+
translation = Codes::SampleClass.translate_gender_code(['f', 'm'], :build => :zip)
|
64
|
+
|
65
|
+
assert translation.kind_of? Array
|
66
|
+
assert_equal(['weiblich', 'f'], translation.first)
|
67
|
+
assert_equal(['männlich', 'm'], translation.last)
|
68
|
+
|
69
|
+
translation = Codes::SampleClass.translate_gender_code(['f', 'm'], :locale => :en, :build => :zip)
|
70
|
+
|
71
|
+
assert translation.kind_of? Array
|
72
|
+
assert_equal(['female', 'f'], translation.first)
|
73
|
+
assert_equal(['male', 'm'], translation.last)
|
74
|
+
end
|
75
|
+
|
53
76
|
|
54
77
|
# :type => :lookup -------------------------------------------------------------------
|
55
78
|
def test_code_attribute_lookup_default
|
56
|
-
code_single = Codes::CivilStatus.
|
57
|
-
code_married = Codes::CivilStatus.
|
79
|
+
code_single = Codes::CivilStatus.for_code('single')
|
80
|
+
code_married = Codes::CivilStatus.for_code('married')
|
58
81
|
|
59
82
|
code_client = Codes::SampleClass.new(:civil_status_code => 'single')
|
60
83
|
|
data/test/resources/models.rb
CHANGED
@@ -49,7 +49,7 @@ module Codes
|
|
49
49
|
@@code_cache[code_obj.code_id] = code_obj
|
50
50
|
end
|
51
51
|
|
52
|
-
def self.
|
52
|
+
def self.for_code(code)
|
53
53
|
@@code_cache[code]
|
54
54
|
end
|
55
55
|
end
|
@@ -64,4 +64,13 @@ module Codes
|
|
64
64
|
self.table_name = :codes_ar_code
|
65
65
|
end
|
66
66
|
|
67
|
+
class SegmentModel
|
68
|
+
include CodeBox::CodeAttribute[:i18n_model_segment => :model]
|
69
|
+
|
70
|
+
attr_accessor :gender_code
|
71
|
+
|
72
|
+
# i18n codes
|
73
|
+
code_attribute :gender
|
74
|
+
end
|
75
|
+
|
67
76
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: code-box
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|