assignable_values 0.3.0 → 0.4.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/README.md
CHANGED
@@ -103,6 +103,18 @@ Defaults can be lambdas:
|
|
103
103
|
|
104
104
|
The lambda will be evaluated in the context of the record instance.
|
105
105
|
|
106
|
+
You can also default a secondary default that is only set if the primary default value is not assignable:
|
107
|
+
|
108
|
+
class Song < ActiveRecord::Base
|
109
|
+
assignable_values_for :year, :default => 1999, :secondary_default => lambda { Date.today.year } do
|
110
|
+
(Date.today.year - 2) .. Date.today.year
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
If called in 2013 the code above will fall back to:
|
115
|
+
|
116
|
+
Song.new.year # => 2013
|
117
|
+
|
106
118
|
|
107
119
|
### Allowing blank values
|
108
120
|
|
@@ -3,7 +3,7 @@ module AssignableValues
|
|
3
3
|
module Restriction
|
4
4
|
class Base
|
5
5
|
|
6
|
-
attr_reader :model, :property, :options, :values, :default
|
6
|
+
attr_reader :model, :property, :options, :values, :default, :secondary_default
|
7
7
|
|
8
8
|
def initialize(model, property, options, &values)
|
9
9
|
@model = model
|
@@ -11,7 +11,7 @@ module AssignableValues
|
|
11
11
|
@options = options
|
12
12
|
@values = values
|
13
13
|
ensure_values_given
|
14
|
-
setup_default
|
14
|
+
setup_default
|
15
15
|
define_assignable_values_method
|
16
16
|
setup_validation
|
17
17
|
end
|
@@ -20,8 +20,9 @@ module AssignableValues
|
|
20
20
|
value = current_value(record)
|
21
21
|
unless allow_blank? && value.blank?
|
22
22
|
begin
|
23
|
-
|
24
|
-
|
23
|
+
unless assignable_value?(record, value)
|
24
|
+
record.errors.add(property, not_included_error_message)
|
25
|
+
end
|
25
26
|
rescue DelegateUnavailable
|
26
27
|
# if the delegate is unavailable, the validation is skipped
|
27
28
|
end
|
@@ -32,6 +33,10 @@ module AssignableValues
|
|
32
33
|
I18n.t('errors.messages.inclusion', :default => 'is not included in the list')
|
33
34
|
end
|
34
35
|
|
36
|
+
def assignable_value?(record, value)
|
37
|
+
assignable_values(record).include?(value)
|
38
|
+
end
|
39
|
+
|
35
40
|
def assignable_values(record)
|
36
41
|
assignable_values = []
|
37
42
|
old_value = previously_saved_value(record)
|
@@ -43,8 +48,13 @@ module AssignableValues
|
|
43
48
|
|
44
49
|
def set_default(record)
|
45
50
|
if record.new_record? && record.send(property).nil?
|
46
|
-
default_value = default
|
47
|
-
|
51
|
+
default_value = evaluate_default(record, default)
|
52
|
+
if secondary_default? && !assignable_value?(record, default_value)
|
53
|
+
secondary_default_value = evaluate_default(record, secondary_default)
|
54
|
+
if assignable_value?(record, secondary_default_value)
|
55
|
+
default_value = secondary_default_value
|
56
|
+
end
|
57
|
+
end
|
48
58
|
record.send("#{property}=", default_value)
|
49
59
|
end
|
50
60
|
true
|
@@ -52,6 +62,14 @@ module AssignableValues
|
|
52
62
|
|
53
63
|
private
|
54
64
|
|
65
|
+
def evaluate_default(record, value_or_proc)
|
66
|
+
if value_or_proc.is_a?(Proc)
|
67
|
+
record.instance_eval(&value_or_proc)
|
68
|
+
else
|
69
|
+
value_or_proc
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
55
73
|
def parse_values(values)
|
56
74
|
values.to_a
|
57
75
|
end
|
@@ -76,6 +94,10 @@ module AssignableValues
|
|
76
94
|
@options.has_key?(:default)
|
77
95
|
end
|
78
96
|
|
97
|
+
def secondary_default?
|
98
|
+
@options.has_key?(:secondary_default)
|
99
|
+
end
|
100
|
+
|
79
101
|
def allow_blank?
|
80
102
|
@options[:allow_blank]
|
81
103
|
end
|
@@ -89,15 +111,20 @@ module AssignableValues
|
|
89
111
|
end
|
90
112
|
|
91
113
|
def setup_default
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
restriction.
|
114
|
+
if default?
|
115
|
+
@default = options[:default] # for attr_reader
|
116
|
+
@secondary_default = options[:secondary_default] # for attr_reader
|
117
|
+
ensure_after_initialize_callback_enabled
|
118
|
+
restriction = self
|
119
|
+
enhance_model do
|
120
|
+
set_default_method = "set_default_#{restriction.property}"
|
121
|
+
define_method set_default_method do
|
122
|
+
restriction.set_default(self)
|
123
|
+
end
|
124
|
+
after_initialize set_default_method
|
99
125
|
end
|
100
|
-
|
126
|
+
elsif secondary_default?
|
127
|
+
raise AssignableValues::NoDefault, "cannot use the :secondary_default option without a :default option"
|
101
128
|
end
|
102
129
|
end
|
103
130
|
|
@@ -261,6 +261,79 @@ describe AssignableValues::ActiveRecord do
|
|
261
261
|
|
262
262
|
end
|
263
263
|
|
264
|
+
context 'with :secondary_default option' do
|
265
|
+
|
266
|
+
it 'should set a secondary default value if the primary value is not assignable' do
|
267
|
+
klass = disposable_song_class do
|
268
|
+
assignable_values_for :genre, :default => 'techno', :secondary_default => 'rock' do
|
269
|
+
%w[pop rock]
|
270
|
+
end
|
271
|
+
end
|
272
|
+
klass.new.genre.should == 'rock'
|
273
|
+
end
|
274
|
+
|
275
|
+
it 'should not change the default value if the default value is assignable' do
|
276
|
+
klass = disposable_song_class do
|
277
|
+
assignable_values_for :genre, :default => 'pop', :secondary_default => 'rock' do
|
278
|
+
%w[pop rock]
|
279
|
+
end
|
280
|
+
end
|
281
|
+
klass.new.genre.should == 'pop'
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should not change the primary default if the secondary default value isn't assignable either" do
|
285
|
+
klass = disposable_song_class do
|
286
|
+
assignable_values_for :genre, :default => 'techno', :secondary_default => 'jazz' do
|
287
|
+
%w[pop rock]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
klass.new.genre.should == 'techno'
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'should raise an error if used without a :default option' do
|
294
|
+
expect do
|
295
|
+
disposable_song_class do
|
296
|
+
assignable_values_for :genre, :secondary_default => 'pop' do
|
297
|
+
%w[pop rock]
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end.to raise_error(AssignableValues::NoDefault)
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'should allow to set a secondary default through a lambda' do
|
304
|
+
klass = disposable_song_class do
|
305
|
+
assignable_values_for :genre, :default => 'techno', :secondary_default => lambda { 'pop' } do
|
306
|
+
%w[pop rock]
|
307
|
+
end
|
308
|
+
end
|
309
|
+
klass.new.genre.should == 'pop'
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'should evaluate a secondary lambda default in the context of the record instance' do
|
313
|
+
klass = disposable_song_class do
|
314
|
+
assignable_values_for :genre, :default => 'techno', :secondary_default => lambda { default_genre } do
|
315
|
+
%w[pop rock]
|
316
|
+
end
|
317
|
+
def default_genre
|
318
|
+
'pop'
|
319
|
+
end
|
320
|
+
end
|
321
|
+
klass.new.genre.should == 'pop'
|
322
|
+
end
|
323
|
+
|
324
|
+
it 'should not cause the list of assignable values to be evaluated if the :secondary_default option is not used' do
|
325
|
+
klass = disposable_song_class do
|
326
|
+
assignable_values_for :genre, :default => 'techno' do
|
327
|
+
raise "block called!"
|
328
|
+
end
|
329
|
+
end
|
330
|
+
expect do
|
331
|
+
klass.new.genre.should == 'techno'
|
332
|
+
end.to_not raise_error
|
333
|
+
end
|
334
|
+
|
335
|
+
end
|
336
|
+
|
264
337
|
context 'when generating methods to list assignable values' do
|
265
338
|
|
266
339
|
it 'should generate an instance method returning a list of assignable values' do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: assignable_values
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 4
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Henning Koch
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-08-02 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|