code-box 0.5.0 → 0.5.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.lock +7 -7
- data/README.md +90 -32
- data/code-box.gemspec +1 -1
- data/lib/code-box/acts_as_code.rb +60 -22
- data/lib/code-box/version.rb +1 -1
- data/lib/code-box.rb +14 -3
- data/test/code-box/test_acts_as_code.rb +29 -9
- metadata +2 -2
data/Gemfile.lock
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
code-box (0.5.
|
4
|
+
code-box (0.5.1)
|
5
5
|
activerecord (~> 3.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activemodel (3.2.
|
11
|
-
activesupport (= 3.2.
|
10
|
+
activemodel (3.2.7)
|
11
|
+
activesupport (= 3.2.7)
|
12
12
|
builder (~> 3.0.0)
|
13
|
-
activerecord (3.2.
|
14
|
-
activemodel (= 3.2.
|
15
|
-
activesupport (= 3.2.
|
13
|
+
activerecord (3.2.7)
|
14
|
+
activemodel (= 3.2.7)
|
15
|
+
activesupport (= 3.2.7)
|
16
16
|
arel (~> 3.0.2)
|
17
17
|
tzinfo (~> 0.3.29)
|
18
|
-
activesupport (3.2.
|
18
|
+
activesupport (3.2.7)
|
19
19
|
i18n (~> 0.6)
|
20
20
|
multi_json (~> 1.0)
|
21
21
|
arel (3.0.2)
|
data/README.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# Notes
|
2
|
+
|
3
|
+
If you re using ActiveRecord ~> 4.0.0 use the version ~> 0.6
|
4
|
+
If you re using ActiveRecord ~> 3.0 use the version ~> 0.5.0
|
5
|
+
|
1
6
|
# CodeBox::CodeAttribute
|
2
7
|
|
3
8
|
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.
|
@@ -134,12 +139,12 @@ Options are:
|
|
134
139
|
If `true` the uniqueness validation is scoped by the attribute `type` (default false).
|
135
140
|
* `:uniqueness_case_sensitive => true`
|
136
141
|
If `true` the the uniqueness validation is case sensitive (default true).
|
137
|
-
* `:position_attr => :position
|
142
|
+
* `:position_attr => :position`
|
138
143
|
If present, the order when fetching the codes is done with this expression (default scope - means - if you want to omit the order used `unscoped` on any AR operation).
|
139
144
|
|
140
|
-
All options except `:code_attribute` are used
|
145
|
+
All options except `:code_attribute` are used __only__ for ActiveRecord models.
|
141
146
|
|
142
|
-
If `*codes` are provided the following code constants will be defined
|
147
|
+
If `*codes` are provided the following code constants will be defined as shown in the example below.
|
143
148
|
|
144
149
|
__IMPORTANT__ Code object constants will only be created when the code object is not an ActiveRecord model!
|
145
150
|
|
@@ -150,7 +155,7 @@ __IMPORTANT__ Code object constants will only be created when the code object is
|
|
150
155
|
# acts_as_code('male', 'female') # Code attribute name will be 'code'
|
151
156
|
|
152
157
|
|
153
|
-
# Given codes 'male'
|
158
|
+
# Given codes 'male' and 'female' the following constants will be defined:
|
154
159
|
#
|
155
160
|
# module Codes
|
156
161
|
# Male = 'male'
|
@@ -158,7 +163,7 @@ __IMPORTANT__ Code object constants will only be created when the code object is
|
|
158
163
|
# All = [Male, Female]
|
159
164
|
# end
|
160
165
|
#
|
161
|
-
# Below constants
|
166
|
+
# Below constants are only currently only defined if the hosting class not an ActiveRecod model (as in this sample).
|
162
167
|
# Male = Gender.new('male')
|
163
168
|
# Female = Gender.new('female')
|
164
169
|
# All = [Male, Female]
|
@@ -166,7 +171,35 @@ __IMPORTANT__ Code object constants will only be created when the code object is
|
|
166
171
|
end
|
167
172
|
|
168
173
|
|
169
|
-
|
174
|
+
If `*codes` are provided - in addition the following test_methods are defined:
|
175
|
+
|
176
|
+
class Gender
|
177
|
+
include CodeBox::ActsAsCode['male', 'female'] # Code attribute name will be 'code'
|
178
|
+
# Above is a shortcut for...
|
179
|
+
# include CodeBox::ActsAsCode
|
180
|
+
# acts_as_code('male', 'female') # Code attribute name will be 'code'
|
181
|
+
|
182
|
+
|
183
|
+
# Given codes 'male' and 'female' the following constants will be defined:
|
184
|
+
# ... al the stuff above
|
185
|
+
#
|
186
|
+
# def male?
|
187
|
+
# code == Codes::Male
|
188
|
+
# end
|
189
|
+
#
|
190
|
+
# def female?
|
191
|
+
# code == Codes::Female
|
192
|
+
# end
|
193
|
+
#
|
194
|
+
end
|
195
|
+
|
196
|
+
Pass the option `define_test_methods: false` if you don't want to have test-methods generated.
|
197
|
+
If you prefer the all test-methods prefixed with e.g. `is_` so the methods above look like `is_male?` then you can configure this
|
198
|
+
globaly by defining `CodeBox.test_method_prefix='is_'`.
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
In addition `acts_as_code` defines the following methods:
|
170
203
|
|
171
204
|
* `.for_code(code)`
|
172
205
|
Answers the code object for the given code (fetched from cache)
|
@@ -174,18 +207,37 @@ Furthermote àcts_as_code` defines the following methods:
|
|
174
207
|
* `#translated_code(locale=I18n.locale, *other_locale_options)`
|
175
208
|
Translates the code stored in `code`
|
176
209
|
|
177
|
-
*
|
178
|
-
Translates
|
179
|
-
|
180
|
-
* `.translate_code(codes_and_options)`
|
181
|
-
<br/>Translates a single code if `code` is a code, an array of codes of `code` is an array.
|
210
|
+
* `.translate_code(codes_and_options)`
|
211
|
+
Translates a single code if `code` is a code, an array of codes of `code` is an array.
|
182
212
|
If code is an array the option :build => :zip can be used to build a select option capable array (e.g `[['Switzerland', 'SUI'],['Germany', 'GER'],['Denmark', 'DEN']]`)
|
183
213
|
|
184
214
|
* `.build_select_options(codes_and_options)`
|
185
|
-
Build an options array from the passed codes (all codes if no codes are passed). Add an empty option at the beginning if the option `:
|
215
|
+
Build an options array from the passed codes (all codes if no codes are passed). Add an empty option at the beginning if the option `:include_empty` is passed. If `:include_empty` is…
|
216
|
+
|
217
|
+
* `true`, then options label is derived from the I18n tranlsation of the key defined in CodeBox.i18n_empty_options_key (default is `shared.options.pls_select` - you can change this default). The value of the option is `nil` by default.
|
218
|
+
* `false` then no empty option is defined (default)
|
219
|
+
* a String then the string is used as label. The value of the option is `nil` by default.
|
220
|
+
* a String starting with `i18n.` the the string is considered as a tranlation key (without the `i18n.` part). Value is nil by default.
|
221
|
+
* is a Hash then the value is take from the Hashs value for key `:value` (nil if not present), and the label is taken from the value of key `:label` (default CodeBox.i18n_empty_option_key). If a String is present it is interpreted as a plain label or I18n key as described above.
|
186
222
|
|
187
|
-
|
188
|
-
|
223
|
+
``Examples
|
224
|
+
|
225
|
+
.build_select_options(include_empty: true)
|
226
|
+
|
227
|
+
is same as …
|
228
|
+
|
229
|
+
.build_select_options(include_empty: {})
|
230
|
+
|
231
|
+
is same as …
|
232
|
+
|
233
|
+
.build_select_options(include_empty: {label: nil, value: nil})
|
234
|
+
|
235
|
+
is same as …
|
236
|
+
|
237
|
+
.build_select_options(include_empty: {label: '<your default key in CodeBox.i18n_empty_options_key>', value: nil})
|
238
|
+
|
239
|
+
* `.clear_code_cache`
|
240
|
+
Clears the cache so its build up again lazy when needed form all codes.
|
189
241
|
|
190
242
|
* Passing
|
191
243
|
|
@@ -216,29 +268,23 @@ Assuming we have a simple ruby class with default code attribute 'code' we can d
|
|
216
268
|
# raise "Sublass responsibility. You should implement '.all' returning all codes"
|
217
269
|
# end
|
218
270
|
|
219
|
-
# @return [Array] List if all code objects (instances of this)
|
271
|
+
# @return [Array] List if all code objects (instances of this) - is implemented when codes are defined.
|
220
272
|
def self.all
|
221
|
-
|
273
|
+
raise 'Class responsibility - implement method .all returning all code models.'
|
222
274
|
end
|
223
275
|
|
224
276
|
end
|
225
277
|
|
226
|
-
Configuration options are:
|
227
|
-
|
228
|
-
:type => :poro #(default, other :active_record)
|
229
|
-
:code_attribute => :code #(default) or any other name as symbol
|
230
|
-
|
231
|
-
|
232
278
|
|
233
279
|
#### ActiveRecod code objects (:active_record)
|
234
280
|
|
235
281
|
Assuming we have an ActiveRecod code class with `code_attribute :code` we can defined such a class like
|
236
282
|
|
237
283
|
class Codes::MySpecificCode < ActiveRecord::Base
|
238
|
-
include CodeBox::ActsAsCode[
|
284
|
+
include CodeBox::ActsAsCode[]
|
239
285
|
# Above is actually a shortcut for:
|
240
286
|
# include CodeBox::ActsAsCode
|
241
|
-
# acts_as_code
|
287
|
+
# acts_as_code
|
242
288
|
|
243
289
|
# Above include creates the following:
|
244
290
|
#
|
@@ -249,19 +295,31 @@ Assuming we have an ActiveRecod code class with `code_attribute :code` we can de
|
|
249
295
|
|
250
296
|
end
|
251
297
|
|
252
|
-
Configuration options are:
|
253
|
-
|
254
|
-
:type => :active_record # other :poro(default)
|
255
|
-
:code_attribute => :code # (default) or any other name as symbol
|
256
|
-
:polymorphic => false # (default). If `true` the uniqueness validation is scope by the attribute `type`
|
257
|
-
:uniqueness_case_sensitive => true # (default). If `false` the the uniqueness validation is case insensitive
|
258
|
-
:position_attr => :position # If present, the order when fetching the codes is done with this expression (default scope - means - if you want to omit the order used `unscoped` on any AR operation).
|
259
|
-
|
260
298
|
|
261
299
|
|
262
300
|
### Examples
|
263
301
|
TO BE DONE…
|
264
302
|
|
303
|
+
## Changelog
|
304
|
+
|
305
|
+
### Version 0.5.1
|
306
|
+
* Adding testing methods for codes objects. E.g. Code-Object with code 'my_code' get method `#codeObjectInstance.my_code?` defined.
|
307
|
+
* Method `.build_select_options` has been changed so you can pass in more flexible empty option configuration (see Readme).
|
308
|
+
* Ugrade of Rails 4 Version pending…
|
309
|
+
|
310
|
+
### Version 0.6.0
|
311
|
+
* Moving to activerecord 4.0.
|
312
|
+
|
313
|
+
### Version 0.5.0
|
314
|
+
* Change constant definition. Create code constants in a Codes module so the can be included in other places - an document it.
|
315
|
+
* Remove option `:model_type. The option is obsolte and can be derived from the including module.
|
316
|
+
|
317
|
+
### Version 0.4.*
|
318
|
+
* Define constant whens defining codes.
|
319
|
+
|
320
|
+
### Version 0.3.*
|
321
|
+
* Need to scan the logs…
|
322
|
+
|
265
323
|
## Contributing
|
266
324
|
|
267
325
|
1. Fork it!
|
data/code-box.gemspec
CHANGED
@@ -47,21 +47,23 @@ module CodeBox
|
|
47
47
|
|
48
48
|
module ClassMethods
|
49
49
|
DefaultOptions = {
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
50
|
+
code_attribute: 'code',
|
51
|
+
sti: false,
|
52
|
+
uniqueness_case_sensitive: true,
|
53
|
+
position_attr: :position,
|
54
|
+
define_test_methods: true,
|
54
55
|
}
|
55
56
|
|
56
57
|
def acts_as_code(*codes_and_or_options)
|
57
|
-
options
|
58
|
-
codes
|
59
|
-
opts
|
60
|
-
code_attr
|
61
|
-
position_attr
|
62
|
-
case_sensitive
|
58
|
+
options = codes_and_or_options.extract_options!
|
59
|
+
codes = codes_and_or_options
|
60
|
+
opts = DefaultOptions.merge(options)
|
61
|
+
code_attr = opts[:code_attribute].to_s
|
62
|
+
position_attr = opts[:position_attribute]
|
63
|
+
case_sensitive = opts[:uniqueness_case_sensitive]
|
64
|
+
define_test_methods = opts[:define_test_methods]
|
63
65
|
|
64
|
-
model_type
|
66
|
+
model_type = self.ancestors.include?('ActiveRecord::Base'.constantize) ? :active_record : :poro
|
65
67
|
|
66
68
|
class_eval <<-RUBY_
|
67
69
|
def translated_#{code_attr}(locale = I18n.locale, *options)
|
@@ -98,12 +100,32 @@ module CodeBox
|
|
98
100
|
end
|
99
101
|
|
100
102
|
def self.build_select_options(*args)
|
101
|
-
options
|
102
|
-
codes
|
103
|
-
|
103
|
+
options = args.extract_options!
|
104
|
+
codes = args.empty? ? #{code_attr.pluralize.camelize}::All : args
|
105
|
+
include_empty = options[:include_empty] || false
|
106
|
+
locale = options.fetch(:locale, I18n.locale)
|
107
|
+
|
108
|
+
label, value = case include_empty
|
109
|
+
when Hash
|
110
|
+
[
|
111
|
+
include_empty.fetch(:label, "i18n.#{CodeBox.i18n_empty_options_key}"),
|
112
|
+
include_empty.fetch(:value, nil)
|
113
|
+
]
|
114
|
+
when TrueClass
|
115
|
+
[ "i18n.#{CodeBox.i18n_empty_options_key}", nil ]
|
116
|
+
when String
|
117
|
+
[ include_empty, nil ]
|
118
|
+
else # is something falsish
|
119
|
+
[]
|
120
|
+
end
|
121
|
+
|
104
122
|
|
123
|
+
# If starts with 'i18n.' it is considered an I18n key, else the label itself
|
105
124
|
options = translate_#{code_attr}(codes, build: :zip)
|
106
|
-
|
125
|
+
if include_empty
|
126
|
+
label = I18n.t(label[5..-1], locale: locale) if label.starts_with?('i18n.')
|
127
|
+
options.unshift [label, value]
|
128
|
+
end
|
107
129
|
|
108
130
|
options
|
109
131
|
end
|
@@ -142,7 +164,7 @@ module CodeBox
|
|
142
164
|
validates_presence_of :#{code_attr}
|
143
165
|
validates_uniqueness_of :#{code_attr}#{opts[:sti] ? ', :scope => :type' : ' '}, :case_sensitive => #{case_sensitive}
|
144
166
|
|
145
|
-
default_scope order('#{order_expression}')
|
167
|
+
default_scope -> { order('#{order_expression}') }
|
146
168
|
CODE
|
147
169
|
|
148
170
|
when :poro
|
@@ -156,7 +178,7 @@ module CodeBox
|
|
156
178
|
end
|
157
179
|
|
158
180
|
def self.all
|
159
|
-
raise 'Class responsibility'
|
181
|
+
raise 'Class responsibility - implement method .all returning all code models.'
|
160
182
|
end
|
161
183
|
|
162
184
|
def hash
|
@@ -175,14 +197,11 @@ module CodeBox
|
|
175
197
|
raise ArgumentError, "'#{model_type}' is not a valid type. Use :active_record or :poro(default) instead"
|
176
198
|
end
|
177
199
|
|
178
|
-
define_codes(*codes)
|
200
|
+
define_codes(*codes, define_test_methods) unless codes.empty?
|
179
201
|
end
|
180
202
|
|
181
|
-
def define_codes(*codes)
|
182
|
-
return if codes.empty?
|
183
|
-
|
203
|
+
def define_codes(*codes, define_test_methods)
|
184
204
|
# --- Define the code constants...
|
185
|
-
|
186
205
|
code_attr = self._code_box_code_attr_name
|
187
206
|
model_type = self.ancestors.include?('ActiveRecord::Base'.constantize) ? :active_record : :poro
|
188
207
|
|
@@ -204,8 +223,27 @@ module CodeBox
|
|
204
223
|
codes_module.const_set('All', constants.values.compact)
|
205
224
|
end
|
206
225
|
|
226
|
+
|
227
|
+
# Define test methods for each code like e.g.
|
228
|
+
# def married?
|
229
|
+
# code == Codes::Married
|
230
|
+
# end
|
231
|
+
if define_test_methods
|
232
|
+
method_prefix = CodeBox.test_method_prefix
|
233
|
+
|
234
|
+
codes.each do |code|
|
235
|
+
method_name = "#{method_prefix}#{code.to_s}"
|
236
|
+
class_eval <<-CODE
|
237
|
+
def #{method_name}?
|
238
|
+
#{code_attr} == #{module_name}::#{code.to_s.camelize}
|
239
|
+
end
|
240
|
+
CODE
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
207
244
|
return if model_type == :active_record
|
208
245
|
|
246
|
+
|
209
247
|
# --- Define the code instance constants...
|
210
248
|
|
211
249
|
constants = {}
|
data/lib/code-box/version.rb
CHANGED
data/lib/code-box.rb
CHANGED
@@ -5,8 +5,9 @@ require 'code-box/acts_as_code'
|
|
5
5
|
|
6
6
|
module CodeBox
|
7
7
|
Config = {
|
8
|
-
:
|
9
|
-
|
8
|
+
i18n_model_segment: :activerecord,
|
9
|
+
i18n_empty_options_key: 'shared.options.pls_select',
|
10
|
+
test_method_prefix: '',
|
10
11
|
}
|
11
12
|
|
12
13
|
def i18n_model_segment=(segment)
|
@@ -25,5 +26,15 @@ module CodeBox
|
|
25
26
|
Config[:i18n_empty_options_key]
|
26
27
|
end
|
27
28
|
|
28
|
-
|
29
|
+
def test_method_prefix=(prefix)
|
30
|
+
Config[:test_method_prefix] = (prefix.nil? ? '' : prefix.strip)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_method_prefix
|
34
|
+
Config[:test_method_prefix]
|
35
|
+
end
|
36
|
+
|
37
|
+
module_function :i18n_model_segment, :i18n_model_segment=,
|
38
|
+
:i18n_empty_options_key, :i18n_empty_options_key=,
|
39
|
+
:test_method_prefix, :test_method_prefix=
|
29
40
|
end
|
@@ -57,15 +57,15 @@ class TestActsAsCode < Test::Unit::TestCase
|
|
57
57
|
|
58
58
|
def test_code_instance_constant_definitions_w_define_code
|
59
59
|
# Constants
|
60
|
-
assert Codes::
|
61
|
-
assert Codes::
|
62
|
-
assert Codes::
|
60
|
+
assert Codes::CivilStatus.const_defined?('Single')
|
61
|
+
assert Codes::CivilStatus.const_defined?('Married')
|
62
|
+
assert Codes::CivilStatus.const_defined?('All')
|
63
63
|
|
64
64
|
# Constants-Values
|
65
|
-
assert_equal [Codes::
|
66
|
-
assert_equal [Codes::
|
67
|
-
assert_equal Codes::
|
68
|
-
assert_equal Codes::
|
65
|
+
assert_equal [Codes::CivilStatus::Single, Codes::CivilStatus::Married], Codes::CivilStatus::All
|
66
|
+
assert_equal [Codes::CivilStatus::Single, Codes::CivilStatus::Married], Codes::CivilStatus.all
|
67
|
+
assert_equal Codes::CivilStatus::Single.code, 'single'
|
68
|
+
assert_equal Codes::CivilStatus::Married.code, 'married'
|
69
69
|
end
|
70
70
|
|
71
71
|
def test_code_translation
|
@@ -79,9 +79,29 @@ class TestActsAsCode < Test::Unit::TestCase
|
|
79
79
|
options_array = Codes::CivilStatus.build_select_options
|
80
80
|
assert_equal options_array.size, 2
|
81
81
|
|
82
|
-
options_array = Codes::CivilStatus.build_select_options(
|
82
|
+
options_array = Codes::CivilStatus.build_select_options(include_empty: true)
|
83
|
+
assert_equal options_array.size, 3
|
84
|
+
assert_equal options_array.first[1], nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_options_building_with_text_label
|
88
|
+
options_array = Codes::CivilStatus.build_select_options(include_empty: { label: 'MyLabel' })
|
89
|
+
assert_equal options_array.size, 3
|
90
|
+
assert_equal options_array.first[0], 'MyLabel'
|
91
|
+
assert_equal options_array.first[1], nil
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_options_building_with_custom_value
|
95
|
+
options_array = Codes::CivilStatus.build_select_options(include_empty: { value: 'all' })
|
96
|
+
assert_equal options_array.size, 3
|
97
|
+
assert_equal options_array.first[1], 'all'
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_options_building_with_custom_label_and_value
|
101
|
+
options_array = Codes::CivilStatus.build_select_options(include_empty: { label: 'Yaiii', value: 'all' })
|
83
102
|
assert_equal options_array.size, 3
|
84
|
-
|
103
|
+
assert_equal options_array.first[0], 'Yaiii'
|
104
|
+
assert_equal options_array.first[1], 'all'
|
85
105
|
end
|
86
106
|
|
87
107
|
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.5.
|
4
|
+
version: 0.5.1
|
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: 2013-09-
|
12
|
+
date: 2013-09-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|