assignable_values 0.15.0 → 0.16.3
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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +44 -27
- data/CHANGELOG.md +33 -0
- data/Gemfile +1 -1
- data/{gemfiles/Gemfile.2.3 → Gemfile.2.3} +1 -1
- data/{gemfiles/Gemfile.2.3.lock → Gemfile.2.3.lock} +2 -2
- data/{gemfiles/Gemfile.3.2 → Gemfile.3.2} +1 -1
- data/{gemfiles/Gemfile.3.2.lock → Gemfile.3.2.lock} +2 -2
- data/{gemfiles/Gemfile.4.2 → Gemfile.4.2} +1 -1
- data/{gemfiles/Gemfile.4.2.lock → Gemfile.4.2.lock} +2 -2
- data/{gemfiles/Gemfile.5.0 → Gemfile.5.0} +1 -1
- data/{gemfiles/Gemfile.5.0.lock → Gemfile.5.0.lock} +2 -2
- data/{gemfiles/Gemfile.5.1 → Gemfile.5.1} +1 -1
- data/{gemfiles/Gemfile.5.1.lock → Gemfile.5.1.lock} +3 -3
- data/{gemfiles/Gemfile.5.1.pg → Gemfile.5.1.pg} +1 -1
- data/{gemfiles/Gemfile.5.1.pg.lock → Gemfile.5.1.pg.lock} +2 -2
- data/Gemfile.6.0.pg +16 -0
- data/Gemfile.6.0.pg.lock +68 -0
- data/Gemfile.lock +1 -1
- data/README.md +14 -11
- data/lib/assignable_values/active_record/restriction/base.rb +30 -10
- data/lib/assignable_values/active_record/restriction/scalar_attribute.rb +18 -5
- data/lib/assignable_values/version.rb +1 -1
- data/spec/assignable_values/active_record_spec.rb +239 -55
- data/spec/support/database.rb +1 -1
- data/spec/support/i18n.yml +4 -1
- data/spec/support/models.rb +3 -3
- metadata +17 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 400d27572075ed4ae3361303c97ccb7acf0afb00e63cfdc8e3a667d8da73b874
|
|
4
|
+
data.tar.gz: 20e2628282f45a9265d036a0b3ca1078a5bb5532cf06654d05c79bd67c878d96
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0d8d5c406b2829863c62fe04851341667ce4f49cc2e6f3c29e6e58cc4710fe70d123ac7cbc315f56f8fdd1734dcab7c5b9693186bd9b12033db3df03fd686261
|
|
7
|
+
data.tar.gz: d0e460d55fa4ce7d26207a239778177f56a4c1dcd73a8f7ee7aa6167094b55b75af84a0a8a9cc9e9e3a371c693b4fb813df16978057e545b4dbaa50415926668
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.3.
|
|
1
|
+
2.3.8
|
data/.travis.yml
CHANGED
|
@@ -1,63 +1,80 @@
|
|
|
1
1
|
language: ruby
|
|
2
2
|
|
|
3
|
+
dist: trusty
|
|
4
|
+
|
|
3
5
|
rvm:
|
|
4
6
|
- 1.8.7
|
|
5
7
|
- 2.1.8
|
|
6
|
-
- 2.3.
|
|
8
|
+
- 2.3.8
|
|
7
9
|
- 2.4.2
|
|
10
|
+
- 2.5.3
|
|
8
11
|
|
|
9
12
|
gemfile:
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
13
|
+
- Gemfile.2.3
|
|
14
|
+
- Gemfile.3.2
|
|
15
|
+
- Gemfile.4.2
|
|
16
|
+
- Gemfile.5.0
|
|
17
|
+
- Gemfile.5.1
|
|
18
|
+
- Gemfile.5.1.pg
|
|
19
|
+
- Gemfile.6.0.pg
|
|
16
20
|
|
|
17
21
|
matrix:
|
|
18
22
|
exclude:
|
|
19
|
-
- gemfile:
|
|
23
|
+
- gemfile: Gemfile.2.3
|
|
20
24
|
rvm: 2.1.8
|
|
21
|
-
- gemfile:
|
|
22
|
-
rvm: 2.3.
|
|
23
|
-
- gemfile:
|
|
25
|
+
- gemfile: Gemfile.2.3
|
|
26
|
+
rvm: 2.3.8
|
|
27
|
+
- gemfile: Gemfile.2.3
|
|
24
28
|
rvm: 2.4.2
|
|
25
|
-
- gemfile:
|
|
26
|
-
rvm: 2.3
|
|
27
|
-
- gemfile:
|
|
29
|
+
- gemfile: Gemfile.2.3
|
|
30
|
+
rvm: 2.5.3
|
|
31
|
+
- gemfile: Gemfile.3.2
|
|
32
|
+
rvm: 2.3.8
|
|
33
|
+
- gemfile: Gemfile.3.2
|
|
28
34
|
rvm: 2.4.2
|
|
29
|
-
- gemfile:
|
|
35
|
+
- gemfile: Gemfile.3.2
|
|
36
|
+
rvm: 2.5.3
|
|
37
|
+
- gemfile: Gemfile.4.2
|
|
30
38
|
rvm: 1.8.7
|
|
31
|
-
- gemfile:
|
|
39
|
+
- gemfile: Gemfile.4.2
|
|
32
40
|
rvm: 2.4.2
|
|
33
|
-
- gemfile:
|
|
41
|
+
- gemfile: Gemfile.4.2
|
|
42
|
+
rvm: 2.5.3
|
|
43
|
+
- gemfile: Gemfile.5.0
|
|
44
|
+
rvm: 1.8.7
|
|
45
|
+
- gemfile: Gemfile.5.0
|
|
34
46
|
rvm: 2.1.8
|
|
35
|
-
- gemfile:
|
|
47
|
+
- gemfile: Gemfile.5.1
|
|
36
48
|
rvm: 1.8.7
|
|
37
|
-
- gemfile:
|
|
49
|
+
- gemfile: Gemfile.5.1
|
|
38
50
|
rvm: 2.1.8
|
|
39
|
-
- gemfile:
|
|
51
|
+
- gemfile: Gemfile.5.1.pg
|
|
40
52
|
rvm: 1.8.7
|
|
41
|
-
- gemfile:
|
|
53
|
+
- gemfile: Gemfile.5.1.pg
|
|
42
54
|
rvm: 2.1.8
|
|
43
|
-
- gemfile:
|
|
55
|
+
- gemfile: Gemfile.6.0.pg
|
|
44
56
|
rvm: 1.8.7
|
|
57
|
+
- gemfile: Gemfile.6.0.pg
|
|
58
|
+
rvm: 2.1.8
|
|
59
|
+
- gemfile: Gemfile.6.0.pg
|
|
60
|
+
rvm: 2.3.8
|
|
61
|
+
- gemfile: Gemfile.6.0.pg
|
|
62
|
+
rvm: 2.4.2
|
|
63
|
+
|
|
64
|
+
addons:
|
|
65
|
+
postgresql: "9.4"
|
|
45
66
|
|
|
46
67
|
sudo: false
|
|
47
68
|
|
|
48
69
|
cache: bundler
|
|
49
70
|
|
|
50
|
-
notifications:
|
|
51
|
-
email:
|
|
52
|
-
- fail@makandra.de
|
|
53
|
-
|
|
54
71
|
before_script:
|
|
55
72
|
- psql -c 'create database assignable_values_test;' -U postgres
|
|
56
73
|
- mysql -e 'create database IF NOT EXISTS assignable_values_test;'
|
|
57
74
|
|
|
58
75
|
install:
|
|
59
76
|
# Old Travis CI bundler explodes when lockfile version doesn't match recently bumped version
|
|
60
|
-
- gem install bundler --version='=1.
|
|
77
|
+
- gem install bundler --version='=1.17.3'
|
|
61
78
|
# This is the default Travis CI install step
|
|
62
79
|
- bundle install --jobs=3 --retry=3 --deployment --path=${BUNDLE_PATH:-vendor/bundle}
|
|
63
80
|
|
data/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,39 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
|
|
|
8
8
|
|
|
9
9
|
### Compatible changes
|
|
10
10
|
|
|
11
|
+
## 0.16.3 - 2020-10-15
|
|
12
|
+
|
|
13
|
+
### Compatible changes
|
|
14
|
+
|
|
15
|
+
- No longer crashes when assigning `nil` to an attribute with assignable values that are provided as a scope.
|
|
16
|
+
|
|
17
|
+
## 0.16.2 - 2020-10-06
|
|
18
|
+
|
|
19
|
+
### Compatible changes
|
|
20
|
+
|
|
21
|
+
- when given a scope, do not load all records to memory during validation
|
|
22
|
+
|
|
23
|
+
## 0.16.1 - 2019-05-14
|
|
24
|
+
|
|
25
|
+
### Compatible changes
|
|
26
|
+
|
|
27
|
+
- add tests for Rails 6
|
|
28
|
+
- Humanized assignable value methods now also take the include_old_values option (fixes #25)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## 0.16.0 - 2019-02-20
|
|
32
|
+
|
|
33
|
+
### Breaking changes
|
|
34
|
+
|
|
35
|
+
- fix arity bug
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## 0.15.1 - 2018-11-05
|
|
39
|
+
|
|
40
|
+
### Compatible changes
|
|
41
|
+
|
|
42
|
+
- Add `#humanized_values` for the `multiple: true` case.
|
|
43
|
+
|
|
11
44
|
|
|
12
45
|
## 0.15.0 - 2018-10-26
|
|
13
46
|
|
data/Gemfile
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
./
|
|
1
|
+
./Gemfile.4.2
|
data/Gemfile.6.0.pg
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
# Runtime dependencies
|
|
4
|
+
gem 'activerecord', '~>6.0.0'
|
|
5
|
+
gem 'i18n'
|
|
6
|
+
gem 'pg', '<1'
|
|
7
|
+
|
|
8
|
+
# Development dependencies
|
|
9
|
+
gem 'rake'
|
|
10
|
+
gem 'database_cleaner'
|
|
11
|
+
gem 'rspec'
|
|
12
|
+
gem 'rspec_candy'
|
|
13
|
+
gem 'gemika'
|
|
14
|
+
|
|
15
|
+
# Gem under test
|
|
16
|
+
gem 'assignable_values', :path => '.'
|
data/Gemfile.6.0.pg.lock
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
assignable_values (0.16.3)
|
|
5
|
+
activerecord (>= 2.3)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
activemodel (6.0.0)
|
|
11
|
+
activesupport (= 6.0.0)
|
|
12
|
+
activerecord (6.0.0)
|
|
13
|
+
activemodel (= 6.0.0)
|
|
14
|
+
activesupport (= 6.0.0)
|
|
15
|
+
activesupport (6.0.0)
|
|
16
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
17
|
+
i18n (>= 0.7, < 2)
|
|
18
|
+
minitest (~> 5.1)
|
|
19
|
+
tzinfo (~> 1.1)
|
|
20
|
+
zeitwerk (~> 2.1, >= 2.1.8)
|
|
21
|
+
concurrent-ruby (1.1.5)
|
|
22
|
+
database_cleaner (1.7.0)
|
|
23
|
+
diff-lcs (1.3)
|
|
24
|
+
gemika (0.3.4)
|
|
25
|
+
i18n (1.6.0)
|
|
26
|
+
concurrent-ruby (~> 1.0)
|
|
27
|
+
minitest (5.11.3)
|
|
28
|
+
pg (0.21.0)
|
|
29
|
+
rake (12.3.2)
|
|
30
|
+
rspec (3.8.0)
|
|
31
|
+
rspec-core (~> 3.8.0)
|
|
32
|
+
rspec-expectations (~> 3.8.0)
|
|
33
|
+
rspec-mocks (~> 3.8.0)
|
|
34
|
+
rspec-core (3.8.0)
|
|
35
|
+
rspec-support (~> 3.8.0)
|
|
36
|
+
rspec-expectations (3.8.2)
|
|
37
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
38
|
+
rspec-support (~> 3.8.0)
|
|
39
|
+
rspec-mocks (3.8.0)
|
|
40
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
41
|
+
rspec-support (~> 3.8.0)
|
|
42
|
+
rspec-support (3.8.0)
|
|
43
|
+
rspec_candy (0.5.1)
|
|
44
|
+
rspec
|
|
45
|
+
sneaky-save
|
|
46
|
+
sneaky-save (0.1.3)
|
|
47
|
+
activerecord (>= 3.2.0)
|
|
48
|
+
thread_safe (0.3.6)
|
|
49
|
+
tzinfo (1.2.5)
|
|
50
|
+
thread_safe (~> 0.1)
|
|
51
|
+
zeitwerk (2.1.9)
|
|
52
|
+
|
|
53
|
+
PLATFORMS
|
|
54
|
+
ruby
|
|
55
|
+
|
|
56
|
+
DEPENDENCIES
|
|
57
|
+
activerecord (~> 6.0.0)
|
|
58
|
+
assignable_values!
|
|
59
|
+
database_cleaner
|
|
60
|
+
gemika
|
|
61
|
+
i18n
|
|
62
|
+
pg (< 1)
|
|
63
|
+
rake
|
|
64
|
+
rspec
|
|
65
|
+
rspec_candy
|
|
66
|
+
|
|
67
|
+
BUNDLED WITH
|
|
68
|
+
1.17.3
|
data/Gemfile.lock
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
./
|
|
1
|
+
./Gemfile.4.2.lock
|
data/README.md
CHANGED
|
@@ -5,7 +5,7 @@ assignable_values - Enums on vitamins [ on Ruby 1.8.7, 2.1, 2.3, 2.4 and 2.5.
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
Restricting scalar attributes
|
|
@@ -91,7 +91,7 @@ The default is applied to new records:
|
|
|
91
91
|
Defaults can be procs:
|
|
92
92
|
|
|
93
93
|
class Song < ActiveRecord::Base
|
|
94
|
-
assignable_values_for :
|
|
94
|
+
assignable_values_for :year, default: proc { Date.today.year } do
|
|
95
95
|
1980 .. 2011
|
|
96
96
|
end
|
|
97
97
|
end
|
|
@@ -185,8 +185,8 @@ In this case, every *subset* of the given values is valid, for example `['pop',
|
|
|
185
185
|
For humanization, you can still use
|
|
186
186
|
|
|
187
187
|
```
|
|
188
|
-
song.
|
|
189
|
-
song.
|
|
188
|
+
song.humanized_genre('pop') # => "Pop music"
|
|
189
|
+
song.humanized_assignable_genres.last.humanized # => "Electronic music"
|
|
190
190
|
```
|
|
191
191
|
|
|
192
192
|
|
|
@@ -205,7 +205,7 @@ You can restrict `belongs_to` associations in the same manner as scalar attribut
|
|
|
205
205
|
|
|
206
206
|
end
|
|
207
207
|
|
|
208
|
-
Listing and validating
|
|
208
|
+
Listing and validating also works the same:
|
|
209
209
|
|
|
210
210
|
chicane = Artist.create!(name: 'Chicane', signed: true)
|
|
211
211
|
lt2 = Artist.create!(name: 'LT2', signed: false)
|
|
@@ -349,16 +349,19 @@ Development
|
|
|
349
349
|
|
|
350
350
|
There are tests in `spec`. We only accept PRs with tests. To run tests:
|
|
351
351
|
|
|
352
|
-
- Install Ruby 2.
|
|
353
|
-
- Create a local test database `assignable_values_test` in both MySQL and PostgreSQL
|
|
354
|
-
|
|
352
|
+
- Install Ruby 2.3.8
|
|
353
|
+
- Create a local test database `assignable_values_test` in both MySQL and PostgreSQL (see
|
|
354
|
+
`.travis.yml` for commands to do so)
|
|
355
|
+
- Copy `spec/support/database.sample.yml` to `spec/support/database.yml` and enter your local
|
|
356
|
+
credentials for the test databases (postgres entry is not required if you are using a socket
|
|
357
|
+
connection)
|
|
355
358
|
- Install development dependencies using `bundle install`
|
|
356
|
-
- Run tests using `bundle exec
|
|
359
|
+
- Run tests using `bundle exec rake current_rspec`
|
|
357
360
|
|
|
358
361
|
We recommend to test large changes against multiple versions of Ruby and multiple dependency sets. Supported combinations are configured in `.travis.yml`. We provide some rake tasks to help with this:
|
|
359
362
|
|
|
360
|
-
- Install development dependencies using `bundle matrix:install`
|
|
361
|
-
- Run tests using `bundle matrix:spec`
|
|
363
|
+
- Install development dependencies using `bundle exec rake matrix:install`
|
|
364
|
+
- Run tests using `bundle exec rake matrix:spec`
|
|
362
365
|
|
|
363
366
|
Note that we have configured Travis CI to automatically run tests in all supported Ruby versions and dependency sets after each push. We will only merge pull requests after a green Travis build.
|
|
364
367
|
|
|
@@ -48,25 +48,31 @@ module AssignableValues
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def assignable_values(record, options = {})
|
|
51
|
-
|
|
51
|
+
additional_assignable_values = []
|
|
52
52
|
current_values = assignable_values_from_record_or_delegate(record)
|
|
53
53
|
|
|
54
54
|
if options.fetch(:include_old_value, true) && has_previously_saved_value?(record)
|
|
55
55
|
old_value = previously_saved_value(record)
|
|
56
56
|
if @options[:multiple]
|
|
57
57
|
if old_value.is_a?(Array)
|
|
58
|
-
|
|
58
|
+
additional_assignable_values |= old_value
|
|
59
59
|
end
|
|
60
60
|
elsif !old_value.blank? && !current_values.include?(old_value)
|
|
61
|
-
|
|
61
|
+
additional_assignable_values << old_value
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
assignable_values += current_values
|
|
66
65
|
if options[:decorate]
|
|
67
|
-
|
|
66
|
+
current_values = decorate_values(current_values)
|
|
67
|
+
additional_assignable_values = decorate_values(additional_assignable_values)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
if additional_assignable_values.present?
|
|
71
|
+
# will not keep current_values scoped
|
|
72
|
+
additional_assignable_values + current_values
|
|
73
|
+
else
|
|
74
|
+
current_values
|
|
68
75
|
end
|
|
69
|
-
assignable_values
|
|
70
76
|
end
|
|
71
77
|
|
|
72
78
|
private
|
|
@@ -94,7 +100,21 @@ module AssignableValues
|
|
|
94
100
|
def assignable_single_value?(record, value)
|
|
95
101
|
(has_previously_saved_value?(record) && value == previously_saved_value(record)) ||
|
|
96
102
|
(value.blank? && allow_blank?(record)) ||
|
|
97
|
-
|
|
103
|
+
included_in_assignable_values?(record, value)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def included_in_assignable_values?(record, value)
|
|
107
|
+
values_or_scope = assignable_values(record, :include_old_value => false)
|
|
108
|
+
|
|
109
|
+
if is_scope?(values_or_scope)
|
|
110
|
+
values_or_scope.exists?(value.id) unless value.nil?
|
|
111
|
+
else
|
|
112
|
+
values_or_scope.include?(value)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def is_scope?(object)
|
|
117
|
+
object.respond_to?(:scoped) || object.respond_to?(:all)
|
|
98
118
|
end
|
|
99
119
|
|
|
100
120
|
def assignable_multi_value?(record, value)
|
|
@@ -217,9 +237,9 @@ module AssignableValues
|
|
|
217
237
|
|
|
218
238
|
def assignable_values_from_record_or_delegate(record)
|
|
219
239
|
if delegate?
|
|
220
|
-
assignable_values_from_delegate(record)
|
|
240
|
+
assignable_values_from_delegate(record)
|
|
221
241
|
else
|
|
222
|
-
record.instance_exec(&@values)
|
|
242
|
+
record.instance_exec(&@values)
|
|
223
243
|
end
|
|
224
244
|
end
|
|
225
245
|
|
|
@@ -240,7 +260,7 @@ module AssignableValues
|
|
|
240
260
|
delegate = delegate(record)
|
|
241
261
|
delegate.present? or raise DelegateUnavailable, "Cannot query a nil delegate for assignable values"
|
|
242
262
|
delegate_query_method = :"assignable_#{model.name.underscore.gsub('/', '_')}_#{property.to_s.pluralize}"
|
|
243
|
-
args = delegate.method(delegate_query_method).arity ==
|
|
263
|
+
args = delegate.method(delegate_query_method).arity == 0 ? [] : [record]
|
|
244
264
|
delegate.send(delegate_query_method, *args)
|
|
245
265
|
end
|
|
246
266
|
|
|
@@ -17,8 +17,8 @@ module AssignableValues
|
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def humanized_assignable_values(record)
|
|
21
|
-
values = assignable_values(record)
|
|
20
|
+
def humanized_assignable_values(record, options = {})
|
|
21
|
+
values = assignable_values(record, options)
|
|
22
22
|
values.collect do |value|
|
|
23
23
|
HumanizedValue.new(value, humanized_value(value))
|
|
24
24
|
end
|
|
@@ -37,7 +37,7 @@ module AssignableValues
|
|
|
37
37
|
def define_humanized_value_class_method
|
|
38
38
|
restriction = self
|
|
39
39
|
enhance_model_singleton do
|
|
40
|
-
define_method :"humanized_#{restriction.property}" do |given_value|
|
|
40
|
+
define_method :"humanized_#{restriction.property.to_s.singularize}" do |given_value|
|
|
41
41
|
restriction.humanized_value(given_value)
|
|
42
42
|
end
|
|
43
43
|
end
|
|
@@ -55,6 +55,19 @@ module AssignableValues
|
|
|
55
55
|
value = given_value || send(restriction.property)
|
|
56
56
|
restriction.humanized_value(value)
|
|
57
57
|
end
|
|
58
|
+
|
|
59
|
+
if multiple
|
|
60
|
+
define_method :"humanized_#{restriction.property}" do
|
|
61
|
+
values = send(restriction.property)
|
|
62
|
+
if values.respond_to?(:map)
|
|
63
|
+
values.map do |value|
|
|
64
|
+
restriction.humanized_value(value)
|
|
65
|
+
end
|
|
66
|
+
else
|
|
67
|
+
values
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
58
71
|
end
|
|
59
72
|
end
|
|
60
73
|
|
|
@@ -62,8 +75,8 @@ module AssignableValues
|
|
|
62
75
|
restriction = self
|
|
63
76
|
multiple = @options[:multiple]
|
|
64
77
|
enhance_model do
|
|
65
|
-
define_method :"humanized_assignable_#{restriction.property.to_s.pluralize}" do
|
|
66
|
-
restriction.humanized_assignable_values(self)
|
|
78
|
+
define_method :"humanized_assignable_#{restriction.property.to_s.pluralize}" do |*args|
|
|
79
|
+
restriction.humanized_assignable_values(self, *args)
|
|
67
80
|
end
|
|
68
81
|
|
|
69
82
|
unless multiple
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
require 'ostruct'
|
|
3
3
|
|
|
4
|
+
def save_without_validation(record)
|
|
5
|
+
if ActiveRecord::VERSION::MAJOR < 3
|
|
6
|
+
record.save(false)
|
|
7
|
+
else
|
|
8
|
+
record.save(:validate => false)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
4
12
|
describe AssignableValues::ActiveRecord do
|
|
5
13
|
|
|
6
14
|
describe '.assignable_values' do
|
|
@@ -17,30 +25,30 @@ describe AssignableValues::ActiveRecord do
|
|
|
17
25
|
|
|
18
26
|
before :each do
|
|
19
27
|
@klass = Song.disposable_copy do
|
|
20
|
-
assignable_values_for :
|
|
28
|
+
assignable_values_for :virtual_sub_genre do
|
|
21
29
|
%w[pop rock]
|
|
22
30
|
end
|
|
23
31
|
|
|
24
|
-
assignable_values_for :
|
|
32
|
+
assignable_values_for :virtual_multi_genres, :multiple => true, :allow_blank => true do
|
|
25
33
|
%w[pop rock]
|
|
26
34
|
end
|
|
27
35
|
end
|
|
28
36
|
end
|
|
29
37
|
|
|
30
38
|
it 'should validate that the attribute is allowed' do
|
|
31
|
-
@klass.new(:
|
|
32
|
-
@klass.new(:
|
|
39
|
+
@klass.new(:virtual_sub_genre => 'pop').should be_valid
|
|
40
|
+
@klass.new(:virtual_sub_genre => 'disallowed value').should_not be_valid
|
|
33
41
|
end
|
|
34
42
|
|
|
35
43
|
it 'should not allow nil for the attribute value' do
|
|
36
|
-
@klass.new(:
|
|
44
|
+
@klass.new(:virtual_sub_genre => nil).should_not be_valid
|
|
37
45
|
end
|
|
38
46
|
|
|
39
47
|
it 'should generate a method returning the humanized value' do
|
|
40
|
-
song = @klass.new(:
|
|
41
|
-
song.
|
|
42
|
-
song.
|
|
43
|
-
song.
|
|
48
|
+
song = @klass.new(:virtual_sub_genre => 'pop')
|
|
49
|
+
song.humanized_virtual_sub_genre.should == 'Pop music'
|
|
50
|
+
song.humanized_virtual_sub_genre('rock').should == 'Rock music'
|
|
51
|
+
song.humanized_virtual_multi_genre('rock').should == 'Rock music'
|
|
44
52
|
end
|
|
45
53
|
|
|
46
54
|
end
|
|
@@ -51,21 +59,21 @@ describe AssignableValues::ActiveRecord do
|
|
|
51
59
|
|
|
52
60
|
before :each do
|
|
53
61
|
@klass = Song.disposable_copy do
|
|
54
|
-
assignable_values_for :
|
|
62
|
+
assignable_values_for :virtual_multi_genres, :multiple => true do
|
|
55
63
|
%w[pop rock]
|
|
56
64
|
end
|
|
57
65
|
end
|
|
58
66
|
end
|
|
59
67
|
|
|
60
68
|
it 'should validate that the attribute is a subset' do
|
|
61
|
-
@klass.new(:
|
|
62
|
-
@klass.new(:
|
|
63
|
-
@klass.new(:
|
|
69
|
+
@klass.new(:virtual_multi_genres => ['pop']).should be_valid
|
|
70
|
+
@klass.new(:virtual_multi_genres => ['pop', 'rock']).should be_valid
|
|
71
|
+
@klass.new(:virtual_multi_genres => ['pop', 'disallowed value']).should_not be_valid
|
|
64
72
|
end
|
|
65
73
|
|
|
66
74
|
it 'should not allow nil or [] for allow_blank: false' do
|
|
67
|
-
@klass.new(:
|
|
68
|
-
@klass.new(:
|
|
75
|
+
@klass.new(:virtual_multi_genres => nil).should_not be_valid
|
|
76
|
+
@klass.new(:virtual_multi_genres => []).should_not be_valid
|
|
69
77
|
end
|
|
70
78
|
|
|
71
79
|
end
|
|
@@ -74,15 +82,15 @@ describe AssignableValues::ActiveRecord do
|
|
|
74
82
|
|
|
75
83
|
before :each do
|
|
76
84
|
@klass = Song.disposable_copy do
|
|
77
|
-
assignable_values_for :
|
|
85
|
+
assignable_values_for :virtual_multi_genres, :multiple => true, :allow_blank => true do
|
|
78
86
|
%w[pop rock]
|
|
79
87
|
end
|
|
80
88
|
end
|
|
81
89
|
end
|
|
82
90
|
|
|
83
91
|
it 'should allow nil or [] for allow_blank: false' do
|
|
84
|
-
@klass.new(:
|
|
85
|
-
@klass.new(:
|
|
92
|
+
@klass.new(:virtual_multi_genres => nil).should be_valid
|
|
93
|
+
@klass.new(:virtual_multi_genres => []).should be_valid
|
|
86
94
|
end
|
|
87
95
|
|
|
88
96
|
end
|
|
@@ -98,6 +106,10 @@ describe AssignableValues::ActiveRecord do
|
|
|
98
106
|
assignable_values_for :genre do
|
|
99
107
|
%w[pop rock]
|
|
100
108
|
end
|
|
109
|
+
|
|
110
|
+
assignable_values_for :virtual_multi_genres, :multiple => true, :allow_blank => true do
|
|
111
|
+
%w[pop rock]
|
|
112
|
+
end
|
|
101
113
|
end
|
|
102
114
|
end
|
|
103
115
|
|
|
@@ -159,6 +171,31 @@ describe AssignableValues::ActiveRecord do
|
|
|
159
171
|
@klass.humanized_genre('rock').should == 'Rock music'
|
|
160
172
|
end
|
|
161
173
|
|
|
174
|
+
context 'for multiple: true' do
|
|
175
|
+
it 'should raise when trying to humanize a value without an argument' do
|
|
176
|
+
song = @klass.new
|
|
177
|
+
proc { song.humanized_virtual_multi_genre }.should raise_error(ArgumentError)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it 'should generate an instance method to retrieve the humanization of any given value' do
|
|
181
|
+
song = @klass.new(:genre => 'pop')
|
|
182
|
+
song.humanized_virtual_multi_genre('rock').should == 'Rock music'
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it 'should generate a class method to retrieve the humanization of any given value' do
|
|
186
|
+
@klass.humanized_virtual_multi_genre('rock').should == 'Rock music'
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it 'should generate an instance method to retrieve the humanizations of all current values' do
|
|
190
|
+
song = @klass.new
|
|
191
|
+
song.virtual_multi_genres = nil
|
|
192
|
+
song.humanized_virtual_multi_genres.should == nil
|
|
193
|
+
song.virtual_multi_genres = []
|
|
194
|
+
song.humanized_virtual_multi_genres.should == []
|
|
195
|
+
song.virtual_multi_genres = ['pop', 'rock']
|
|
196
|
+
song.humanized_virtual_multi_genres.should == ['Pop music', 'Rock music']
|
|
197
|
+
end
|
|
198
|
+
end
|
|
162
199
|
end
|
|
163
200
|
|
|
164
201
|
context 'if the :allow_blank option is set to true' do
|
|
@@ -226,11 +263,11 @@ describe AssignableValues::ActiveRecord do
|
|
|
226
263
|
context 'if the :message option is set to a string' do
|
|
227
264
|
|
|
228
265
|
before :each do
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
266
|
+
@klass = Song.disposable_copy do
|
|
267
|
+
assignable_values_for :genre, :message => 'should be something different' do
|
|
268
|
+
%w[pop rock]
|
|
269
|
+
end
|
|
270
|
+
end
|
|
234
271
|
end
|
|
235
272
|
|
|
236
273
|
it 'should use this string as a custom error message' do
|
|
@@ -251,43 +288,39 @@ describe AssignableValues::ActiveRecord do
|
|
|
251
288
|
|
|
252
289
|
before :each do
|
|
253
290
|
@klass = Song.disposable_copy do
|
|
254
|
-
assignable_values_for :
|
|
291
|
+
assignable_values_for :multi_genres, :multiple => true do
|
|
255
292
|
%w[pop rock]
|
|
256
293
|
end
|
|
257
294
|
end
|
|
258
295
|
end
|
|
259
296
|
|
|
260
297
|
it 'should validate that the attribute is allowed' do
|
|
261
|
-
@klass.new(:
|
|
262
|
-
@klass.new(:
|
|
263
|
-
@klass.new(:
|
|
298
|
+
@klass.new(:multi_genres => ['pop']).should be_valid
|
|
299
|
+
@klass.new(:multi_genres => ['pop', 'rock']).should be_valid
|
|
300
|
+
@klass.new(:multi_genres => ['pop', 'invalid value']).should_not be_valid
|
|
264
301
|
end
|
|
265
302
|
|
|
266
303
|
it 'should not allow a scalar attribute' do
|
|
267
|
-
@klass.new(:
|
|
304
|
+
@klass.new(:multi_genres => 'pop').should_not be_valid
|
|
268
305
|
end
|
|
269
306
|
|
|
270
307
|
it 'should not allow nil or [] for the attribute value' do
|
|
271
|
-
@klass.new(:
|
|
272
|
-
@klass.new(:
|
|
308
|
+
@klass.new(:multi_genres => nil).should_not be_valid
|
|
309
|
+
@klass.new(:multi_genres => []).should_not be_valid
|
|
273
310
|
end
|
|
274
311
|
|
|
275
312
|
it 'should allow a subset of previously saved values even if that value is no longer allowed' do
|
|
276
|
-
record = @klass.create!(:
|
|
277
|
-
record.
|
|
278
|
-
|
|
279
|
-
record.save(false)
|
|
280
|
-
else
|
|
281
|
-
record.save(:validate => false) # update without validations for the sake of this test
|
|
282
|
-
end
|
|
313
|
+
record = @klass.create!(:multi_genres => ['pop'])
|
|
314
|
+
record.multi_genres = ['pretend', 'previously', 'valid', 'value']
|
|
315
|
+
save_without_validation(record) # update without validation for the sake of this test
|
|
283
316
|
record.reload.should be_valid
|
|
284
|
-
record.
|
|
317
|
+
record.multi_genres = ['valid', 'previously', 'pop']
|
|
285
318
|
record.should be_valid
|
|
286
319
|
end
|
|
287
320
|
|
|
288
321
|
it 'should allow a previously saved, blank value even if that value is no longer allowed' do
|
|
289
|
-
record = @klass.create!(:
|
|
290
|
-
@klass.update_all(:
|
|
322
|
+
record = @klass.create!(:multi_genres => ['pop'])
|
|
323
|
+
@klass.update_all(:multi_genres => []) # update without validations for the sake of this test
|
|
291
324
|
record.reload.should be_valid
|
|
292
325
|
end
|
|
293
326
|
|
|
@@ -297,18 +330,18 @@ describe AssignableValues::ActiveRecord do
|
|
|
297
330
|
|
|
298
331
|
before :each do
|
|
299
332
|
@klass = Song.disposable_copy do
|
|
300
|
-
assignable_values_for :
|
|
333
|
+
assignable_values_for :multi_genres, :multiple => true, :allow_blank => true do
|
|
301
334
|
%w[pop rock]
|
|
302
335
|
end
|
|
303
336
|
end
|
|
304
337
|
end
|
|
305
338
|
|
|
306
339
|
it 'should allow nil for the attribute value' do
|
|
307
|
-
@klass.new(:
|
|
340
|
+
@klass.new(:multi_genres => nil).should be_valid
|
|
308
341
|
end
|
|
309
342
|
|
|
310
343
|
it 'should allow an empty array as value' do
|
|
311
|
-
@klass.new(:
|
|
344
|
+
@klass.new(:multi_genres => []).should be_valid
|
|
312
345
|
end
|
|
313
346
|
|
|
314
347
|
end
|
|
@@ -415,7 +448,7 @@ describe AssignableValues::ActiveRecord do
|
|
|
415
448
|
record.should be_valid
|
|
416
449
|
end
|
|
417
450
|
|
|
418
|
-
it '
|
|
451
|
+
it 'should not allow nil for an association (the "previously saved value") if the record is new' do
|
|
419
452
|
allowed_association = Artist.create!
|
|
420
453
|
klass = Song.disposable_copy
|
|
421
454
|
record = klass.new(:artist => nil)
|
|
@@ -477,6 +510,63 @@ describe AssignableValues::ActiveRecord do
|
|
|
477
510
|
record.valid?
|
|
478
511
|
end
|
|
479
512
|
|
|
513
|
+
context 'when assignable values are provided as an ActiveRecord scope' do
|
|
514
|
+
MyArtist = Artist.disposable_copy
|
|
515
|
+
let(:klass) { Song.disposable_copy }
|
|
516
|
+
|
|
517
|
+
before do
|
|
518
|
+
klass.class_eval do
|
|
519
|
+
assignable_values_for :artist do
|
|
520
|
+
if ::ActiveRecord::VERSION::MAJOR < 4
|
|
521
|
+
MyArtist.scoped({})
|
|
522
|
+
else
|
|
523
|
+
MyArtist.all
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
it 'allows assigning a record from the scope' do
|
|
530
|
+
artist = MyArtist.create!
|
|
531
|
+
song = klass.new(:artist => artist)
|
|
532
|
+
song.should be_valid
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
it 'will not crash during validation when the assigned value is nil' do
|
|
536
|
+
song = klass.new
|
|
537
|
+
expect { song.valid? }.to_not raise_error
|
|
538
|
+
song.errors[:artist_id].should be_present
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
it 'should not load all records into memory' do
|
|
542
|
+
unless ::ActiveRecord::VERSION::MAJOR < 3 # somehow rails 2 still initializes Objects during the scope.exists?-call
|
|
543
|
+
initialized_artists_count = 0
|
|
544
|
+
|
|
545
|
+
MyArtist.class_eval do
|
|
546
|
+
after_initialize :increase_initialized_count
|
|
547
|
+
|
|
548
|
+
define_method :increase_initialized_count do
|
|
549
|
+
initialized_artists_count += 1
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
artist = MyArtist.create!
|
|
554
|
+
initialized_artists_count.should == 1
|
|
555
|
+
|
|
556
|
+
song = klass.new(:artist => artist)
|
|
557
|
+
|
|
558
|
+
song.valid?
|
|
559
|
+
initialized_artists_count.should == 1
|
|
560
|
+
|
|
561
|
+
song.assignable_artists
|
|
562
|
+
initialized_artists_count.should == 1
|
|
563
|
+
|
|
564
|
+
song.assignable_artists.to_a
|
|
565
|
+
initialized_artists_count.should == 2
|
|
566
|
+
end
|
|
567
|
+
end
|
|
568
|
+
end
|
|
569
|
+
|
|
480
570
|
end
|
|
481
571
|
|
|
482
572
|
context 'when delegating using the :through option' do
|
|
@@ -485,7 +575,11 @@ describe AssignableValues::ActiveRecord do
|
|
|
485
575
|
klass = Song.disposable_copy do
|
|
486
576
|
assignable_values_for :genre, :through => :delegate
|
|
487
577
|
def delegate
|
|
488
|
-
|
|
578
|
+
Class.new do
|
|
579
|
+
def assignable_song_genres
|
|
580
|
+
%w[pop rock]
|
|
581
|
+
end
|
|
582
|
+
end.new
|
|
489
583
|
end
|
|
490
584
|
end
|
|
491
585
|
klass.new(:genre => 'pop').should be_valid
|
|
@@ -496,9 +590,14 @@ describe AssignableValues::ActiveRecord do
|
|
|
496
590
|
klass = Song.disposable_copy do
|
|
497
591
|
assignable_values_for :genre, :through => lambda { delegate }
|
|
498
592
|
def delegate
|
|
499
|
-
|
|
593
|
+
Class.new do
|
|
594
|
+
def assignable_song_genres
|
|
595
|
+
%w[pop rock]
|
|
596
|
+
end
|
|
597
|
+
end.new
|
|
500
598
|
end
|
|
501
599
|
end
|
|
600
|
+
|
|
502
601
|
klass.new(:genre => 'pop').should be_valid
|
|
503
602
|
klass.new(:genre => 'disallowed value').should_not be_valid
|
|
504
603
|
end
|
|
@@ -507,7 +606,11 @@ describe AssignableValues::ActiveRecord do
|
|
|
507
606
|
klass = Recording::Vinyl.disposable_copy do
|
|
508
607
|
assignable_values_for :year, :through => :delegate
|
|
509
608
|
def delegate
|
|
510
|
-
|
|
609
|
+
Class.new do
|
|
610
|
+
def assignable_recording_vinyl_years
|
|
611
|
+
[1977, 1980, 1983]
|
|
612
|
+
end
|
|
613
|
+
end.new
|
|
511
614
|
end
|
|
512
615
|
end
|
|
513
616
|
klass.new.assignable_years.should == [1977, 1980, 1983]
|
|
@@ -684,7 +787,7 @@ describe AssignableValues::ActiveRecord do
|
|
|
684
787
|
klass.new.assignable_genres.should == %w[pop rock]
|
|
685
788
|
end
|
|
686
789
|
|
|
687
|
-
it 'should
|
|
790
|
+
it 'should work with ranges' do
|
|
688
791
|
klass = Song.disposable_copy do
|
|
689
792
|
assignable_values_for :year do
|
|
690
793
|
1999..2001
|
|
@@ -710,10 +813,28 @@ describe AssignableValues::ActiveRecord do
|
|
|
710
813
|
assignable_values_for :genre do
|
|
711
814
|
%w[pop rock]
|
|
712
815
|
end
|
|
816
|
+
|
|
817
|
+
assignable_values_for :multi_genres, :multiple => true do
|
|
818
|
+
%w[pop rock]
|
|
819
|
+
end
|
|
713
820
|
end
|
|
714
|
-
record = klass.create!(:genre => 'pop')
|
|
821
|
+
record = klass.create!(:genre => 'pop', :multi_genres => ['rock'])
|
|
715
822
|
klass.update_all(:genre => 'ballad') # update without validation for the sake of this test
|
|
716
823
|
record.reload.assignable_genres.should == %w[ballad pop rock]
|
|
824
|
+
|
|
825
|
+
humanized_genres = record.humanized_assignable_genres
|
|
826
|
+
humanized_genres.collect(&:value).should == %w[ballad pop rock]
|
|
827
|
+
humanized_genres.collect(&:humanized).should == ['Ballad', 'Pop music', 'Rock music']
|
|
828
|
+
humanized_genres.collect(&:to_s).should == ['Ballad', 'Pop music', 'Rock music']
|
|
829
|
+
|
|
830
|
+
record.multi_genres = %w[ballad classic]
|
|
831
|
+
save_without_validation(record) # update without validation for the sake of this test
|
|
832
|
+
record.reload.multi_genres.should == %w[ballad classic]
|
|
833
|
+
|
|
834
|
+
humanized_multi_genres = record.humanized_assignable_multi_genres
|
|
835
|
+
humanized_multi_genres.collect(&:value).should == %w[ballad classic pop rock]
|
|
836
|
+
humanized_multi_genres.collect(&:humanized).should == ['Ballad', 'Classic', 'Pop music', 'Rock music']
|
|
837
|
+
humanized_multi_genres.collect(&:to_s).should == ['Ballad', 'Classic', 'Pop music', 'Rock music']
|
|
717
838
|
end
|
|
718
839
|
|
|
719
840
|
it 'should not prepend a previously saved value to the top of the list if it is still allowed (bugfix)' do
|
|
@@ -753,10 +874,28 @@ describe AssignableValues::ActiveRecord do
|
|
|
753
874
|
assignable_values_for :genre do
|
|
754
875
|
%w[pop rock]
|
|
755
876
|
end
|
|
877
|
+
|
|
878
|
+
assignable_values_for :multi_genres, :multiple => true do
|
|
879
|
+
%w[pop rock]
|
|
880
|
+
end
|
|
756
881
|
end
|
|
757
|
-
record = klass.create!(:genre => 'pop')
|
|
882
|
+
record = klass.create!(:genre => 'pop', :multi_genres => ['rock'])
|
|
758
883
|
klass.update_all(:genre => 'ballad') # update without validation for the sake of this test
|
|
759
884
|
record.reload.assignable_genres(:include_old_value => false).should == %w[pop rock]
|
|
885
|
+
|
|
886
|
+
humanized_genres = record.humanized_assignable_genres(:include_old_value => false)
|
|
887
|
+
humanized_genres.collect(&:value).should == %w[pop rock]
|
|
888
|
+
humanized_genres.collect(&:humanized).should == ['Pop music', 'Rock music']
|
|
889
|
+
humanized_genres.collect(&:to_s).should == ['Pop music', 'Rock music']
|
|
890
|
+
|
|
891
|
+
record.multi_genres = %w[ballad classic]
|
|
892
|
+
save_without_validation(record) # update without validation for the sake of this test
|
|
893
|
+
record.reload.multi_genres.should == %w[ballad classic]
|
|
894
|
+
|
|
895
|
+
humanized_multi_genres = record.humanized_assignable_multi_genres(:include_old_value => false)
|
|
896
|
+
humanized_multi_genres.collect(&:value).should == %w[pop rock]
|
|
897
|
+
humanized_multi_genres.collect(&:humanized).should == ['Pop music', 'Rock music']
|
|
898
|
+
humanized_multi_genres.collect(&:to_s).should == ['Pop music', 'Rock music']
|
|
760
899
|
end
|
|
761
900
|
|
|
762
901
|
it 'should allow omitting a previously saved association' do
|
|
@@ -897,7 +1036,41 @@ describe AssignableValues::ActiveRecord do
|
|
|
897
1036
|
delegate = Object.new
|
|
898
1037
|
def delegate.assignable_song_genres(record)
|
|
899
1038
|
record_received(record)
|
|
900
|
-
|
|
1039
|
+
%w[pop rock]
|
|
1040
|
+
end
|
|
1041
|
+
klass = Song.disposable_copy do
|
|
1042
|
+
assignable_values_for :genre, :through => :delegate
|
|
1043
|
+
define_method :delegate do
|
|
1044
|
+
delegate
|
|
1045
|
+
end
|
|
1046
|
+
end
|
|
1047
|
+
record = klass.new
|
|
1048
|
+
delegate.should_receive(:record_received).with(record)
|
|
1049
|
+
record.assignable_genres.should == %w[pop rock]
|
|
1050
|
+
end
|
|
1051
|
+
|
|
1052
|
+
it "should call the given method on the delegate if the delegate's query method takes no arguments" do
|
|
1053
|
+
delegate = Object.new
|
|
1054
|
+
def delegate.assignable_song_genres
|
|
1055
|
+
no_record_received
|
|
1056
|
+
%w[pop rock]
|
|
1057
|
+
end
|
|
1058
|
+
klass = Song.disposable_copy do
|
|
1059
|
+
assignable_values_for :genre, :through => :delegate
|
|
1060
|
+
define_method :delegate do
|
|
1061
|
+
delegate
|
|
1062
|
+
end
|
|
1063
|
+
end
|
|
1064
|
+
record = klass.new
|
|
1065
|
+
delegate.should_receive(:no_record_received)
|
|
1066
|
+
record.assignable_genres.should == %w[pop rock]
|
|
1067
|
+
end
|
|
1068
|
+
|
|
1069
|
+
it "should pass the record to the given method if the delegate's query method takes variable arguments" do
|
|
1070
|
+
delegate = Object.new
|
|
1071
|
+
def delegate.assignable_song_genres(*records)
|
|
1072
|
+
record_received(*records)
|
|
1073
|
+
%w[pop rock]
|
|
901
1074
|
end
|
|
902
1075
|
klass = Song.disposable_copy do
|
|
903
1076
|
assignable_values_for :genre, :through => :delegate
|
|
@@ -910,6 +1083,21 @@ describe AssignableValues::ActiveRecord do
|
|
|
910
1083
|
record.assignable_genres.should == %w[pop rock]
|
|
911
1084
|
end
|
|
912
1085
|
|
|
1086
|
+
it "should raise an error if the delegate's query method takes more than one argument" do
|
|
1087
|
+
delegate = Object.new
|
|
1088
|
+
def delegate.assignable_song_genres(record, other_arg)
|
|
1089
|
+
%w[pop rock]
|
|
1090
|
+
end
|
|
1091
|
+
klass = Song.disposable_copy do
|
|
1092
|
+
assignable_values_for :genre, :through => :delegate
|
|
1093
|
+
define_method :delegate do
|
|
1094
|
+
delegate
|
|
1095
|
+
end
|
|
1096
|
+
end
|
|
1097
|
+
record = klass.new
|
|
1098
|
+
expect{record.assignable_genres}.to raise_error(ArgumentError)
|
|
1099
|
+
end
|
|
1100
|
+
|
|
913
1101
|
it 'should raise an error if the given method returns nil' do
|
|
914
1102
|
klass = Song.disposable_copy do
|
|
915
1103
|
assignable_values_for :genre, :through => :delegate
|
|
@@ -919,11 +1107,7 @@ describe AssignableValues::ActiveRecord do
|
|
|
919
1107
|
end
|
|
920
1108
|
expect { klass.new.assignable_genres }.to raise_error(AssignableValues::DelegateUnavailable)
|
|
921
1109
|
end
|
|
922
|
-
|
|
923
1110
|
end
|
|
924
|
-
|
|
925
1111
|
end
|
|
926
|
-
|
|
927
1112
|
end
|
|
928
|
-
|
|
929
1113
|
end
|
data/spec/support/database.rb
CHANGED
data/spec/support/i18n.yml
CHANGED
data/spec/support/models.rb
CHANGED
|
@@ -8,11 +8,11 @@ class Song < ActiveRecord::Base
|
|
|
8
8
|
|
|
9
9
|
belongs_to :artist
|
|
10
10
|
|
|
11
|
-
attr_accessor :
|
|
11
|
+
attr_accessor :virtual_sub_genre, :virtual_sub_genres, :virtual_multi_genres
|
|
12
12
|
|
|
13
|
-
if ActiveRecord::VERSION::MAJOR < 4 || !Song.new(:
|
|
13
|
+
if ActiveRecord::VERSION::MAJOR < 4 || !Song.new(:multi_genres => ['test']).multi_genres.is_a?(Array)
|
|
14
14
|
# Rails 4 or not postgres
|
|
15
|
-
serialize :
|
|
15
|
+
serialize :multi_genres
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: assignable_values
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.16.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Henning Koch
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-10-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -36,23 +36,25 @@ files:
|
|
|
36
36
|
- ".travis.yml"
|
|
37
37
|
- CHANGELOG.md
|
|
38
38
|
- Gemfile
|
|
39
|
+
- Gemfile.2.3
|
|
40
|
+
- Gemfile.2.3.lock
|
|
41
|
+
- Gemfile.3.2
|
|
42
|
+
- Gemfile.3.2.lock
|
|
43
|
+
- Gemfile.4.2
|
|
44
|
+
- Gemfile.4.2.lock
|
|
45
|
+
- Gemfile.5.0
|
|
46
|
+
- Gemfile.5.0.lock
|
|
47
|
+
- Gemfile.5.1
|
|
48
|
+
- Gemfile.5.1.lock
|
|
49
|
+
- Gemfile.5.1.pg
|
|
50
|
+
- Gemfile.5.1.pg.lock
|
|
51
|
+
- Gemfile.6.0.pg
|
|
52
|
+
- Gemfile.6.0.pg.lock
|
|
39
53
|
- Gemfile.lock
|
|
40
54
|
- LICENSE
|
|
41
55
|
- README.md
|
|
42
56
|
- Rakefile
|
|
43
57
|
- assignable_values.gemspec
|
|
44
|
-
- gemfiles/Gemfile.2.3
|
|
45
|
-
- gemfiles/Gemfile.2.3.lock
|
|
46
|
-
- gemfiles/Gemfile.3.2
|
|
47
|
-
- gemfiles/Gemfile.3.2.lock
|
|
48
|
-
- gemfiles/Gemfile.4.2
|
|
49
|
-
- gemfiles/Gemfile.4.2.lock
|
|
50
|
-
- gemfiles/Gemfile.5.0
|
|
51
|
-
- gemfiles/Gemfile.5.0.lock
|
|
52
|
-
- gemfiles/Gemfile.5.1
|
|
53
|
-
- gemfiles/Gemfile.5.1.lock
|
|
54
|
-
- gemfiles/Gemfile.5.1.pg
|
|
55
|
-
- gemfiles/Gemfile.5.1.pg.lock
|
|
56
58
|
- lib/assignable_values.rb
|
|
57
59
|
- lib/assignable_values/active_record.rb
|
|
58
60
|
- lib/assignable_values/active_record/restriction/base.rb
|
|
@@ -89,8 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
89
91
|
- !ruby/object:Gem::Version
|
|
90
92
|
version: '0'
|
|
91
93
|
requirements: []
|
|
92
|
-
|
|
93
|
-
rubygems_version: 2.7.7
|
|
94
|
+
rubygems_version: 3.1.4
|
|
94
95
|
signing_key:
|
|
95
96
|
specification_version: 4
|
|
96
97
|
summary: Restrict the values assignable to ActiveRecord attributes or associations
|