code-box 0.0.2 → 0.1.0
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.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
|