validation_scopes 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -1
- data/README.md +78 -13
- data/VERSION +1 -1
- data/lib/validation_scopes.rb +7 -4
- data/validation_scopes.gemspec +21 -23
- metadata +23 -12
- data/.gitignore +0 -21
data/CHANGELOG
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
== 0.3.1 2011-02-24
|
2
|
+
|
3
|
+
* Added Rails3 compatibility
|
4
|
+
|
1
5
|
== 0.3.0 2009-01-04
|
2
6
|
|
3
7
|
* Fixed problem with DelegateClass not picking up method definitions that come after the validation_scope block.
|
@@ -8,4 +12,4 @@
|
|
8
12
|
|
9
13
|
== 0.1.0 2009-01-03
|
10
14
|
|
11
|
-
* Initial release. Only tested within an app. Probably has lots of bugs. Test suite forthcoming.
|
15
|
+
* Initial release. Only tested within an app. Probably has lots of bugs. Test suite forthcoming.
|
data/README.md
CHANGED
@@ -1,43 +1,108 @@
|
|
1
1
|
# Validation Scopes
|
2
2
|
|
3
|
-
This gem adds a simple class method `validation_scope` to
|
3
|
+
This gem adds a simple class method `validation_scope` to ActiveRecord. This generates a new collection of
|
4
|
+
`ActiveRecord::Errors` that can be manipulated independently of the standard `errors`, `valid?` and `save` methods. The
|
5
|
+
full power of ActiveRecord validations are preserved in these distinct error collections, including all the macros.
|
6
|
+
|
7
|
+
For example, in addition to standard errors that prevent an object from being saved to the database, you may want
|
8
|
+
a second collection of warnings that you display to the user or otherwise shape the control flow:
|
4
9
|
|
5
10
|
class Film < ActiveRecord::Base
|
11
|
+
validates_presence_of :title # Standard errors
|
12
|
+
|
6
13
|
validation_scope :warnings do |s|
|
7
|
-
s.
|
14
|
+
s.validate :ensure_title_is_capitalized
|
15
|
+
s.validate { |r| r.warnings.add_to_base("Inline warning") }
|
16
|
+
s.validates_presence_of…
|
17
|
+
s.validates_inclusion_of…
|
18
|
+
s.validates_each…
|
19
|
+
s.validates_on_create…
|
20
|
+
end
|
21
|
+
|
22
|
+
def ensure_title_is_capitalized
|
23
|
+
warnings.add(:title, "should be capitalized") unless title =~ %r{\A[A-Z]}
|
8
24
|
end
|
9
25
|
end
|
10
26
|
|
11
|
-
The generated scope produces 3 helper methods based on the symbol passed to the validation_scope method. Continuing the
|
27
|
+
The generated scope produces 3 helper methods based on the symbol passed to the validation_scope method. Continuing the
|
28
|
+
previous example:
|
12
29
|
|
13
|
-
film.
|
30
|
+
film = Film.new(:title => 'lowercase title')
|
31
|
+
film.valid?
|
32
|
+
=> true
|
33
|
+
|
34
|
+
film.no_warnings? # analagous to valid?
|
35
|
+
=> false
|
36
|
+
|
37
|
+
film.has_warnings? # analagous to invalid?
|
38
|
+
=> true
|
39
|
+
|
40
|
+
film.warnings # analagous to film.errors
|
14
41
|
=> #<ActiveRecord::Errors>
|
15
42
|
|
16
|
-
film.
|
43
|
+
film.warnings.full_messages
|
44
|
+
=> ["Title should be capitalized", "Inline warning"]
|
45
|
+
|
46
|
+
film.errors.full_messages
|
47
|
+
=> []
|
48
|
+
|
49
|
+
film.save
|
17
50
|
=> true
|
18
51
|
|
19
|
-
|
20
|
-
|
52
|
+
One rough edge at the moment is when you want to use the builtin `error_messages_for` helper in your views. That helper
|
53
|
+
does not accept an `ActiveRecord::Errors` object directly. Instead you need to pass it the proxy object that
|
54
|
+
`ValidationScopes` creates to encapsulate the generated error set:
|
21
55
|
|
22
|
-
|
56
|
+
error_messages_for :object => film.validation_scope_proxy_for_warnings
|
57
|
+
|
58
|
+
## Compatibility
|
59
|
+
|
60
|
+
Should work for Ruby 1.8 and 1.9, as well as Rails 2.x and 3.x; Battle-tested in the formers.
|
61
|
+
|
62
|
+
## Installation
|
63
|
+
|
64
|
+
The usual:
|
65
|
+
|
66
|
+
gem install validation_scopes
|
67
|
+
|
68
|
+
In your Gemfile:
|
69
|
+
|
70
|
+
gem 'validation_scopes'
|
71
|
+
|
72
|
+
Or old-school Rails-style, in your environment.rb:
|
73
|
+
|
74
|
+
config.gem 'validation_scopes'
|
75
|
+
|
76
|
+
Outside of Rails:
|
77
|
+
|
78
|
+
require 'validation_scopes'
|
23
79
|
|
24
80
|
|
25
81
|
## Caveats
|
26
82
|
|
27
|
-
Due to the use of a proxy DelegateClass to store each additional set of validations, and some heavy meta-programming to
|
83
|
+
Due to the use of a proxy DelegateClass to store each additional set of validations, and some heavy meta-programming to
|
84
|
+
tie it all together with a clean API, there are likely to be some weird edge cases. Please let me know if you discover
|
85
|
+
anything wonky. I believe the opacity of the solution is worth the convenience it provides in exposing the entirety of
|
86
|
+
the Validations API.
|
28
87
|
|
29
88
|
### Don't use private methods
|
30
89
|
|
31
|
-
Because the any validation method supplied as a symbol (eg. `validate :verify_something`) is actually running in the
|
90
|
+
Because the any validation method supplied as a symbol (eg. `validate :verify_something`) is actually running in the
|
91
|
+
context of a delegate class, private methods won't work as they would in standard validations.
|
32
92
|
|
33
93
|
|
34
94
|
## Implementation
|
35
95
|
|
36
|
-
|
96
|
+
I had a lot of fun writing this gem even though the result isn't exactly a shining example elegant code. An [article
|
97
|
+
about the design process](http://www.darwinweb.net/articles/80) is on my blog.
|
98
|
+
|
99
|
+
|
100
|
+
## TODO
|
37
101
|
|
38
|
-
|
102
|
+
* In Rails 3 validations are no longer coupled to ActiveRecord. As part of of ActiveModel, validations can be included
|
103
|
+
in any object. It shouldn't be too much work to make validation_scopes work with arbitrary models as well.
|
39
104
|
|
40
105
|
|
41
106
|
## Copyright
|
42
107
|
|
43
|
-
Copyright (c) 2010 Gabe da Silveira. See LICENSE for details.
|
108
|
+
Copyright (c) 2010,2011 Gabe da Silveira. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/lib/validation_scopes.rb
CHANGED
@@ -11,7 +11,10 @@ module ValidationScopes
|
|
11
11
|
base_class = self
|
12
12
|
deferred_proxy_class_declaration = Proc.new do
|
13
13
|
proxy_class = Class.new(DelegateClass(base_class)) do
|
14
|
-
|
14
|
+
validations_module = defined?(ActiveModel) ? ActiveModel::Validations : ActiveRecord::Validations
|
15
|
+
errors_class = defined?(ActiveModel) ? ActiveModel::Errors : ActiveRecord::Errors
|
16
|
+
|
17
|
+
include validations_module
|
15
18
|
|
16
19
|
def initialize(record)
|
17
20
|
@base_record = record
|
@@ -19,8 +22,8 @@ module ValidationScopes
|
|
19
22
|
end
|
20
23
|
|
21
24
|
# Hack since DelegateClass doesn't seem to be making AR::Base class methods available.
|
22
|
-
|
23
|
-
@errors ||=
|
25
|
+
define_method("errors") do
|
26
|
+
@errors ||= errors_class.new(@base_record)
|
24
27
|
end
|
25
28
|
end
|
26
29
|
|
@@ -56,4 +59,4 @@ module ValidationScopes
|
|
56
59
|
end
|
57
60
|
end
|
58
61
|
|
59
|
-
ActiveRecord::Base.send(:include, ValidationScopes)
|
62
|
+
ActiveRecord::Base.send(:include, ValidationScopes)
|
data/validation_scopes.gemspec
CHANGED
@@ -1,54 +1,52 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{validation_scopes}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Gabe da Silveira"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2011-02-24}
|
13
13
|
s.description = %q{Define additional sets of validations beyond the standard "errors" that is tied to the ActiveRecord life-cycle. These additional sets can be defined with all the standard ActiveRecord::Validation macros, and the resulting collection is a standard ActiveRecord::Errors object.}
|
14
14
|
s.email = %q{gabe@websaviour.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
|
17
|
+
"README.md"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
"validation_scopes.gemspec"
|
21
|
+
"CHANGELOG",
|
22
|
+
"LICENSE",
|
23
|
+
"README.md",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/validation_scopes.rb",
|
27
|
+
"test/db/schema.rb",
|
28
|
+
"test/fixtures/users.yml",
|
29
|
+
"test/helper.rb",
|
30
|
+
"test/models/user.rb",
|
31
|
+
"test/test_validation_scopes.rb",
|
32
|
+
"validation_scopes.gemspec"
|
34
33
|
]
|
35
34
|
s.homepage = %q{http://github.com/dasil003/validation_scopes}
|
36
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
37
35
|
s.require_paths = ["lib"]
|
38
|
-
s.rubygems_version = %q{1.3.
|
36
|
+
s.rubygems_version = %q{1.3.7}
|
39
37
|
s.summary = %q{Create sets of validations independent of the life-cycle of an ActiveRecord object}
|
40
38
|
s.test_files = [
|
41
39
|
"test/db/schema.rb",
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
"test/helper.rb",
|
41
|
+
"test/models/user.rb",
|
42
|
+
"test/test_validation_scopes.rb"
|
45
43
|
]
|
46
44
|
|
47
45
|
if s.respond_to? :specification_version then
|
48
46
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
49
47
|
s.specification_version = 3
|
50
48
|
|
51
|
-
if Gem::Version.new(Gem::
|
49
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
52
50
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
53
51
|
else
|
54
52
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: validation_scopes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 3
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Gabe da Silveira
|
@@ -9,19 +14,22 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date:
|
17
|
+
date: 2011-02-24 00:00:00 -08:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: shoulda
|
17
|
-
|
18
|
-
|
19
|
-
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
20
25
|
requirements:
|
21
26
|
- - ">="
|
22
27
|
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
23
30
|
version: "0"
|
24
|
-
|
31
|
+
type: :development
|
32
|
+
version_requirements: *id001
|
25
33
|
description: Define additional sets of validations beyond the standard "errors" that is tied to the ActiveRecord life-cycle. These additional sets can be defined with all the standard ActiveRecord::Validation macros, and the resulting collection is a standard ActiveRecord::Errors object.
|
26
34
|
email: gabe@websaviour.com
|
27
35
|
executables: []
|
@@ -33,7 +41,6 @@ extra_rdoc_files:
|
|
33
41
|
- README.md
|
34
42
|
files:
|
35
43
|
- .document
|
36
|
-
- .gitignore
|
37
44
|
- CHANGELOG
|
38
45
|
- LICENSE
|
39
46
|
- README.md
|
@@ -51,26 +58,30 @@ homepage: http://github.com/dasil003/validation_scopes
|
|
51
58
|
licenses: []
|
52
59
|
|
53
60
|
post_install_message:
|
54
|
-
rdoc_options:
|
55
|
-
|
61
|
+
rdoc_options: []
|
62
|
+
|
56
63
|
require_paths:
|
57
64
|
- lib
|
58
65
|
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
59
67
|
requirements:
|
60
68
|
- - ">="
|
61
69
|
- !ruby/object:Gem::Version
|
70
|
+
segments:
|
71
|
+
- 0
|
62
72
|
version: "0"
|
63
|
-
version:
|
64
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
65
75
|
requirements:
|
66
76
|
- - ">="
|
67
77
|
- !ruby/object:Gem::Version
|
78
|
+
segments:
|
79
|
+
- 0
|
68
80
|
version: "0"
|
69
|
-
version:
|
70
81
|
requirements: []
|
71
82
|
|
72
83
|
rubyforge_project:
|
73
|
-
rubygems_version: 1.3.
|
84
|
+
rubygems_version: 1.3.7
|
74
85
|
signing_key:
|
75
86
|
specification_version: 3
|
76
87
|
summary: Create sets of validations independent of the life-cycle of an ActiveRecord object
|