at_least_one_existence_validator 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +17 -0
- data/.travis.yml +12 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +75 -0
- data/Rakefile +7 -0
- data/at_least_one_existence_validator.gemspec +28 -0
- data/lib/at_least_one_existence_validator.rb +1 -0
- data/lib/at_least_one_existence_validator/version.rb +1 -1
- data/locales/ru.yml +2 -0
- data/test/test_at_least_one_existence_validator.rb +60 -0
- data/test/test_helper.rb +63 -0
- metadata +51 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f62a850a7099112e9ee71a5d9ffee840abc1b04
|
4
|
+
data.tar.gz: 5c917ebafa5fb5fe21f6f1565ece0b81b17dbae4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 508a2aa970b537f4a468115b1f141e0af297cc1c9d1e6f2591e30a6fdc6c313eb4e7cf3983471429a88afcc89569b288affa1b5c7a2ce377561310e9532bd777
|
7
|
+
data.tar.gz: 62479c235d285084d2209b2e75dc23ade20fa4b8a2f2765b3243ca776c1449a2a221b9d04e79e6f38d6acf56ccd43bcfac07a7f4af208cb812ff93db8fac88d0
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Valeriy Utyaganov
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
at\_least\_one\_existence\_validator [![Build Status](https://travis-ci.org/USAWal/at_least_one_existence_validator.png)](https://travis-ci.org/USAWal/at_least_one_existence_validator)
|
2
|
+
====================================
|
3
|
+
|
4
|
+
Easy to use Rails active model validator which tests whether an associated collection will have any objects after saving. It's useful with one-to-many and many-to-many relationships.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
Add to the `Gemfile`:
|
10
|
+
```ruby
|
11
|
+
gem 'at_least_one_validator'
|
12
|
+
```
|
13
|
+
After adding, install it
|
14
|
+
```shell
|
15
|
+
bundle install
|
16
|
+
```
|
17
|
+
|
18
|
+
Usage
|
19
|
+
-----
|
20
|
+
|
21
|
+
Given you have 'Author' model and 'Book' model respectively. Obviously author can write many books and book can be written by many authors but a book must have at least one author, so eventually you have something like this:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
class Author < ActiveRecord::Base
|
25
|
+
has_and_belongs_to_many :books
|
26
|
+
end
|
27
|
+
|
28
|
+
class Book < ActiveRecord::Base
|
29
|
+
has_and_belongs_to_many :authors
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
If you want to use **at_least_one_existence_validator**, you just need to add helper method ```validates_at_least_one_existence_of```to the model class and list all the collections you want to be validated as parameters. Let's do it:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
class Author < ActiveRecord::Base
|
37
|
+
has_and_belongs_to_many :books
|
38
|
+
end
|
39
|
+
|
40
|
+
class Book < ActiveRecord::Base
|
41
|
+
has_and_belongs_to_many :authors
|
42
|
+
|
43
|
+
validates_at_least_one_existence_of :authors
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
This code will test whether the authors of the tested book are marked for destruction or authors are already blank. If they are, validator will add default error message.
|
48
|
+
|
49
|
+
Configuring
|
50
|
+
-----------
|
51
|
+
|
52
|
+
The default error message for English locale is "must have at least one item.". You can specify your own error message adding it with ```at_least_one:``` key to localization backend. Using previous example and standard i18n localization mechanism for static content we do the next:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
# file project_root/config/locales/en.yml
|
56
|
+
en:
|
57
|
+
activerecord:
|
58
|
+
errors:
|
59
|
+
models:
|
60
|
+
book:
|
61
|
+
attributes:
|
62
|
+
authors:
|
63
|
+
at_least_one: 'must have at least one author.'
|
64
|
+
```
|
65
|
+
|
66
|
+
Message for **at_least_one_existence_validator** scoped by book and its authors is changed now.
|
67
|
+
|
68
|
+
Contributing
|
69
|
+
------------
|
70
|
+
|
71
|
+
1. Fork it
|
72
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
73
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
74
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
75
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'at_least_one_existence_validator/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "at_least_one_existence_validator"
|
8
|
+
spec.version = AtLeastOneExistenceValidator::VERSION
|
9
|
+
spec.authors = ["Valeriy Utyaganov"]
|
10
|
+
spec.email = ["usawal@gmail.com"]
|
11
|
+
spec.description = %q{This validator tests whether associated collection is going to be empty after saving. It will be passed if at least one association of the specified collection will exist. The validator provides helper method and default error message.}
|
12
|
+
spec.summary = %q{Validator for associated collection}
|
13
|
+
spec.homepage = "http://github.com/USAWal/at_least_one_existence_validator"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib", "locales"]
|
20
|
+
|
21
|
+
spec.required_ruby_version = ">= 1.9.3"
|
22
|
+
|
23
|
+
spec.add_runtime_dependency "activemodel", ">= 3"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler" , "~> 1.3"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "activerecord"
|
28
|
+
end
|
data/locales/ru.yml
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'at_least_one_existence_validator'
|
5
|
+
require 'active_record'
|
6
|
+
require 'test_helper'
|
7
|
+
|
8
|
+
class ValidatorTest < Test::Unit::TestCase
|
9
|
+
def test_helper_method_existence
|
10
|
+
assert_respond_to ActiveRecord::Base, :validates_at_least_one_existence_of, "ActiveRecord::Base doesn't have helper method"
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_omitted_authors
|
14
|
+
validate book_with_omitted_authors, "Validator is passed if collection is nil"
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_rphaned_book
|
18
|
+
validate orphaned_book, "Validator is passed if collection is empty"
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_book_with_an_author
|
22
|
+
validate book_with_an_author , "Validator isn't passed if collection has only one item", 0
|
23
|
+
validate book_with_an_author(true), "Validator passed if the only item of its collection is marked for destruction"
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_book_with_some_authors
|
27
|
+
validate book_with_some_authors, "Validator isn't passed if all items of its collection are not marked for destruction", 0
|
28
|
+
validate book_with_some_authors([true, false]*2), "Validator isn't passed if some items of its collection are not marked for destruction", 0
|
29
|
+
validate book_with_some_authors([true]*5), "Validator is passed if all the items of its collection are marked for destruction"
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_error_message
|
33
|
+
messages = {
|
34
|
+
en: 'must have at least one item.',
|
35
|
+
ru: 'должен иметь, по крайней мере, один элемент.'
|
36
|
+
}
|
37
|
+
|
38
|
+
missed_locales = messages.keys - I18n.available_locales
|
39
|
+
assert missed_locales.empty?, "Missed locales: #{missed_locales.to_s}"
|
40
|
+
|
41
|
+
surplus_locales = I18n.available_locales - messages.keys
|
42
|
+
assert surplus_locales.empty?, "Surplus locales: #{surplus_locales.to_s}"
|
43
|
+
|
44
|
+
I18n.available_locales.each do |locale|
|
45
|
+
I18n.locale = locale
|
46
|
+
expected = messages[locale]
|
47
|
+
actual = I18n.t 'errors.messages.at_least_one'
|
48
|
+
assert_equal expected, actual, "Expected message is '#{expected}', actual message is '#{actual}', locale is '#{locale.to_s}'"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
include TestHelper
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def validate tested_book, message, errors_size = 1
|
57
|
+
assert_nothing_raised { ActiveModel::Validations::AtLeastOneExistenceValidator.new({ attributes: [:authors] }).validate tested_book }
|
58
|
+
assert tested_book.errors.size == errors_size, message
|
59
|
+
end
|
60
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
module TestHelper
|
2
|
+
private
|
3
|
+
|
4
|
+
class Book
|
5
|
+
attr_accessor :authors
|
6
|
+
attr_reader :errors
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@authors = []
|
10
|
+
@errors = []
|
11
|
+
@errors.define_singleton_method(:add) { |attribute, message| self << { attribute: attribute, message: message } }
|
12
|
+
end
|
13
|
+
|
14
|
+
def read_attribute_for_validation(attribute)
|
15
|
+
self.send(attribute.to_sym)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Author
|
20
|
+
attr_accessor :books
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@books = []
|
24
|
+
end
|
25
|
+
|
26
|
+
def marked_for_destruction?
|
27
|
+
@marked_for_desctruction || false
|
28
|
+
end
|
29
|
+
|
30
|
+
def mark_for_destruction
|
31
|
+
@marked_for_desctruction = true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def book_with_omitted_authors; Book.new ; end
|
36
|
+
|
37
|
+
def orphaned_book ; book ; end
|
38
|
+
|
39
|
+
def book_with_an_author(marked_for_destruction = false)
|
40
|
+
book_by [author(marked_for_destruction)]
|
41
|
+
end
|
42
|
+
|
43
|
+
def book_with_some_authors(config = [false] * 5)
|
44
|
+
book(config.map { |item| author item })
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def book(authors = [])
|
50
|
+
Book.new.tap do |book|
|
51
|
+
book.authors.concat authors
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
alias_method :book_by, :book
|
56
|
+
|
57
|
+
def author(marked = false)
|
58
|
+
Author.new.tap do |author|
|
59
|
+
author.mark_for_destruction if marked
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: at_least_one_existence_validator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Valeriy Utyaganov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-07-
|
11
|
+
date: 2013-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -25,7 +25,35 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activerecord
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
59
|
- - '>='
|
@@ -38,28 +66,34 @@ dependencies:
|
|
38
66
|
- - '>='
|
39
67
|
- !ruby/object:Gem::Version
|
40
68
|
version: '0'
|
41
|
-
description:
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
email: usawal@gmail.com
|
69
|
+
description: This validator tests whether associated collection is going to be empty
|
70
|
+
after saving. It will be passed if at least one association of the specified collection
|
71
|
+
will exist. The validator provides helper method and default error message.
|
72
|
+
email:
|
73
|
+
- usawal@gmail.com
|
47
74
|
executables: []
|
48
75
|
extensions: []
|
49
76
|
extra_rdoc_files: []
|
50
77
|
files:
|
51
|
-
-
|
78
|
+
- .gitignore
|
79
|
+
- .travis.yml
|
80
|
+
- Gemfile
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- at_least_one_existence_validator.gemspec
|
52
85
|
- lib/active_model/validations/at_least_one_existence_validator.rb
|
86
|
+
- lib/at_least_one_existence_validator.rb
|
53
87
|
- lib/at_least_one_existence_validator/version.rb
|
54
88
|
- locales/en.yml
|
55
89
|
- locales/ru.yml
|
90
|
+
- test/test_at_least_one_existence_validator.rb
|
91
|
+
- test/test_helper.rb
|
56
92
|
homepage: http://github.com/USAWal/at_least_one_existence_validator
|
57
93
|
licenses:
|
58
94
|
- MIT
|
59
95
|
metadata: {}
|
60
|
-
post_install_message:
|
61
|
-
- helper method\n :at_least_one - key for error message
|
62
|
-
in i18n \n"
|
96
|
+
post_install_message:
|
63
97
|
rdoc_options: []
|
64
98
|
require_paths:
|
65
99
|
- lib
|
@@ -68,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
68
102
|
requirements:
|
69
103
|
- - '>='
|
70
104
|
- !ruby/object:Gem::Version
|
71
|
-
version: 1.9.
|
105
|
+
version: 1.9.3
|
72
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
107
|
requirements:
|
74
108
|
- - '>='
|
@@ -80,4 +114,6 @@ rubygems_version: 2.0.5
|
|
80
114
|
signing_key:
|
81
115
|
specification_version: 4
|
82
116
|
summary: Validator for associated collection
|
83
|
-
test_files:
|
117
|
+
test_files:
|
118
|
+
- test/test_at_least_one_existence_validator.rb
|
119
|
+
- test/test_helper.rb
|