validation_scopes 0.3.0 → 0.3.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/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 `ActiveRecord::Base`. Inside the block you can define validations that don't apply to the life-cycle of the object (ie. they aren't implicitly checked when the object is saved).
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.validates_presence_of :title
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 previous example:
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.warnings # analagous to film.errors
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.no_warnings? # analagous to film.valid?
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
- film.has_warnings? # analagous to film.invalid?
20
- => false
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
- All standard `ActiveRecord::Validations` should work.
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 tie it all together with a clean API, there are likely to be some unexpected and confusing edge cases. Please let me know if you discover anything wonky. I believe the opacity of the solution is worth the convenience it provides in exposing the entirety of the Validations API.
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 context of a delegate class, private methods won't work as they would in standard validations.
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
- The implementation of this gem is meta-programming heavy and very dependent on the internal structure of ActiveRecord as of Rails 2.3.5. The goal was to be able to utilize the entire functionality of ActiveRecord validations with a minimum of code. The resulting code is a bit more magic than I would have liked, but it seems to be working for me so far. I plan on forward porting to Rails 3 and maybe it will be nicer.
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
- The core of the implemention is a dynamically created proxy_class that has ActiveRecord::Validations included in order to isolate its own copy of @errors. The proxy class is a DelegateClass which gets initialized to the base ActiveRecord object so that validations can use any of the methods of the base object. Although the use of DelegateClass raises a few issues, it seemed like the cleanest way to do the integration so that all of the ActiveRecord::Validations concerns just work without too much regard to the specifics of the method implementations.
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.0
1
+ 0.3.1
@@ -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
- include ActiveRecord::Validations
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
- def errors
23
- @errors ||= ActiveRecord::Errors.new(@base_record)
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)
@@ -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 the gemspec command
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.0"
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{2010-01-04}
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
- "README.md"
17
+ "README.md"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
- ".gitignore",
22
- "CHANGELOG",
23
- "LICENSE",
24
- "README.md",
25
- "Rakefile",
26
- "VERSION",
27
- "lib/validation_scopes.rb",
28
- "test/db/schema.rb",
29
- "test/fixtures/users.yml",
30
- "test/helper.rb",
31
- "test/models/user.rb",
32
- "test/test_validation_scopes.rb",
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.5}
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
- "test/helper.rb",
43
- "test/models/user.rb",
44
- "test/test_validation_scopes.rb"
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::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
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
- version: 0.3.0
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: 2010-01-04 00:00:00 -08:00
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
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
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
- version:
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
- - --charset=UTF-8
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.5
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
data/.gitignore DELETED
@@ -1,21 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC