grouped_validations 0.2.2 → 0.3.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/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gem 'rspec', '~> 2.0.0'
5
+ gem 'activesupport', '~> 3.0.0'
6
+ gem 'activemodel', '~> 3.0.0'
7
+ gem 'ruby-debug'
data/Gemfile.lock ADDED
@@ -0,0 +1,37 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.0.1)
5
+ activesupport (= 3.0.1)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.4.1)
8
+ activesupport (3.0.1)
9
+ builder (2.1.2)
10
+ columnize (0.3.1)
11
+ diff-lcs (1.1.2)
12
+ i18n (0.4.2)
13
+ linecache (0.43)
14
+ rspec (2.0.1)
15
+ rspec-core (~> 2.0.1)
16
+ rspec-expectations (~> 2.0.1)
17
+ rspec-mocks (~> 2.0.1)
18
+ rspec-core (2.0.1)
19
+ rspec-expectations (2.0.1)
20
+ diff-lcs (>= 1.1.2)
21
+ rspec-mocks (2.0.1)
22
+ rspec-core (~> 2.0.1)
23
+ rspec-expectations (~> 2.0.1)
24
+ ruby-debug (0.10.3)
25
+ columnize (>= 0.1)
26
+ ruby-debug-base (~> 0.10.3.0)
27
+ ruby-debug-base (0.10.3)
28
+ linecache (>= 0.3)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ activemodel (~> 3.0.0)
35
+ activesupport (~> 3.0.0)
36
+ rspec (~> 2.0.0)
37
+ ruby-debug
data/README.rdoc CHANGED
@@ -1,10 +1,12 @@
1
1
  = Grouped Validations
2
2
 
3
- Allows you to define validation groups in ActiveRecord for more control over what validations you want to run.
3
+ Allows you to define ActiveModel validation groups for more control over what validations you want to run.
4
4
 
5
5
  This can be useful for multi-page forms or wizard style data entry.
6
6
 
7
- Works with Rails 2.3 and Rails 3 (ActiveRecord only).
7
+ Works with Rails 3.
8
+
9
+ For Rails 2.x support, try version 0.2.2.
8
10
 
9
11
  == Installation
10
12
 
@@ -16,6 +18,7 @@ Add it to your Rails environment gems
16
18
 
17
19
  config.gem 'grouped_validations'
18
20
 
21
+
19
22
  == Usage
20
23
 
21
24
  Define validations as you would normally but inside a validation_group block which you pass a group
@@ -62,8 +65,82 @@ To define validation blocks just use the respective group validation method, lik
62
65
  validate_name_on_update {|r| # something custom on update }
63
66
  end
64
67
 
68
+
69
+ == Group Options
70
+
71
+ You can use a validation group like similar to the with_options method, but for validation methods only.
72
+
73
+ If you pass in an options hash, those options will be applied to each valiation method in the block.
74
+
75
+ validation_group :name, :if => :ready? do
76
+ validates_presence_of :first_name
77
+ validates_presence_of :last_name
78
+ end
79
+
80
+ Which effectively the same as doing the following:
81
+
82
+ validates_presence_of :first_name, :if => :ready?
83
+ validates_presence_of :last_name, :if => :ready?
84
+
85
+ If you set an option for a specific validation method, it will not be overriden with the validation group
86
+ options.
87
+
88
+ validation_group :name, :if => :ready? do
89
+ validates_presence_of :first_name
90
+ validates_presence_of :last_name, :if => {|r| !r.popstar? }
91
+ end
92
+
93
+ The last_name attribute will be required unless the person is a popstar.
94
+
95
+ The options should work for any validation method which calls the validate class method internally. This includes
96
+ all the default validations.
97
+
98
+ For more precision on when to merge the groups options you can pass an argument to the block and use it like a
99
+ with_options call. Then only those validation methods call on the argument will have the options merged in.
100
+
101
+ validation_group :name, :if => :ready? do |options|
102
+ # Options merged
103
+ options.validates_presence_of :first_name
104
+
105
+ # No options merged
106
+ validates_presence_of :last_name
107
+ end
108
+
109
+
110
+ == Grouped Errors
111
+
112
+ The errors for the model can be returned as hash with the group names as the keys. If you have a number of groups
113
+ you can deal with the error messages in specific ways per group.
114
+
115
+ validation_group :name do
116
+ validates_presence_of :first_name
117
+ validates_presence_of :last_name
118
+ end
119
+
120
+ validates_presence_of :sex
121
+
122
+ To access all errors outside of a validation group, use nil as the key:
123
+
124
+ person.grouped_errors[nil]
125
+
126
+ Use the group name as the key for all errors in that group:
127
+
128
+ person.grouped_errors[:name]
129
+
130
+ Be aware that the validations will all be run. If you have just called <tt>valid?</tt> then the same validations will be run
131
+ again and the current state of the object is used. This is for consideration if the validations are expensive, time
132
+ sensitive or you have changed the object after calling <tt>valid?</tt>.
133
+
134
+ You can use the <tt>grouped_errors</tt> method instead of <tt>valid?</tt> to check on a valid object like so:
135
+
136
+ # Validations all run
137
+ if person.grouped_errors.empty?
138
+ # object is valid
139
+ end
140
+
141
+
65
142
  == Credits
66
143
 
67
144
  * Adam Meehan (http://github.com/adzap)
68
145
 
69
- Copyright (c) 2010 Adam Meehan, released under the MIT license
146
+ Copyright (c) 2010-2011 Adam Meehan, released under the MIT license
data/Rakefile CHANGED
@@ -1,47 +1,19 @@
1
- require 'rubygems'
2
- require 'rake/rdoctask'
3
- require 'rake/gempackagetask'
4
- require 'rubygems/specification'
5
- require 'spec/rake/spectask'
6
- require 'lib/grouped_validations/version'
7
-
8
- GEM_NAME = "grouped_validations"
9
- GEM_VERSION = GroupedValidations::VERSION
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
10
3
 
11
- spec = Gem::Specification.new do |s|
12
- s.name = GEM_NAME
13
- s.version = GEM_VERSION
14
- s.platform = Gem::Platform::RUBY
15
- s.rubyforge_project = GEM_NAME
16
- s.has_rdoc = true
17
- s.extra_rdoc_files = ["README.rdoc"]
18
- s.summary = "Define validation groups in ActiveRecord for greater control over which validations to run."
19
- s.description = s.summary
20
- s.author = "Adam Meehan"
21
- s.email = "adam.meehan@gmail.com"
22
- s.homepage = "http://github.com/adzap/grouped_validations"
23
-
24
- s.require_path = 'lib'
25
- s.autorequire = GEM_NAME
26
- s.files = %w(MIT-LICENSE README.rdoc Rakefile) + Dir.glob("{lib,spec}/**/*")
27
- end
4
+ require 'rake/rdoctask'
5
+ require 'rspec/core/rake_task'
28
6
 
29
7
  desc 'Default: run specs.'
30
8
  task :default => :spec
31
9
 
32
- spec_files = Rake::FileList["spec/**/*_spec.rb"]
33
-
34
10
  desc "Run specs"
35
- Spec::Rake::SpecTask.new do |t|
36
- t.spec_files = spec_files
37
- t.spec_opts = ["-c"]
38
- end
11
+ RSpec::Core::RakeTask.new(:spec)
39
12
 
40
13
  desc "Generate code coverage"
41
- Spec::Rake::SpecTask.new(:coverage) do |t|
42
- t.spec_files = spec_files
14
+ RSpec::Core::RakeTask.new(:coverage) do |t|
43
15
  t.rcov = true
44
- t.rcov_opts = ['--exclude', 'spec,/var/lib/gems']
16
+ t.rcov_opts = ['--exclude', 'spec']
45
17
  end
46
18
 
47
19
  desc 'Generate documentation for plugin.'
@@ -52,19 +24,3 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
52
24
  rdoc.rdoc_files.include('README')
53
25
  rdoc.rdoc_files.include('lib/**/*.rb')
54
26
  end
55
-
56
- Rake::GemPackageTask.new(spec) do |pkg|
57
- pkg.gem_spec = spec
58
- end
59
-
60
- desc "install the gem locally"
61
- task :install => [:package] do
62
- sh %{gem install pkg/#{GEM_NAME}-#{GEM_VERSION}}
63
- end
64
-
65
- desc "create a gemspec file"
66
- task :make_spec do
67
- File.open("#{GEM_NAME}.gemspec", "w") do |file|
68
- file.puts spec.to_ruby
69
- end
70
- end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "grouped_validations/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{grouped_validations}
8
+ s.version = GroupedValidations::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Adam Meehan"]
11
+ s.email = %q{adam.meehan@gmail.com}
12
+ s.homepage = %q{http://github.com/adzap/grouped_validations}
13
+ s.summary = %q{Define validation groups in a model for greater control over which validations are run.}
14
+ s.description = s.summary
15
+
16
+ s.rubyforge_project = %q{grouped_validations}
17
+
18
+ s.files = `git ls-files`.split("\n") - %w{ .gitignore .rspec autotest }
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.extra_rdoc_files = ["README.rdoc"]
21
+ s.require_paths = ["lib"]
22
+ s.autorequire = %q{grouped_validations}
23
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'grouped_validations'
@@ -1,61 +1,93 @@
1
+ require 'active_model/validations'
2
+ require 'grouped_validations/active_model'
3
+
1
4
  module GroupedValidations
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_attribute :validation_groups
9
+ self.validation_groups = []
10
+ end
2
11
 
3
12
  module ClassMethods
4
13
 
5
- def validation_group(group, &block)
6
- raise "The validation_group method requires a block" unless block_given?
14
+ def validate(*args, &block)
15
+ return super unless @_current_validation_group
7
16
 
8
- unless self.include?(GroupedValidations::InstanceMethods)
9
- include GroupedValidations::InstanceMethods
17
+ options = args.extract_options!.dup
18
+ unless @_current_validation_group[:with_options]
19
+ options.reverse_merge!(@_current_validation_group.except(:name))
10
20
  end
11
21
 
12
- self.validation_groups ||= []
13
- self.validation_groups << group
14
-
15
- define_group_validation_callbacks group
22
+ if options.key?(:on)
23
+ options = options.dup
24
+ options[:if] = Array.wrap(options[:if])
25
+ options[:if] << "validation_context == :#{options[:on]}"
26
+ end
27
+ args << options
28
+ set_callback(:"validate_#{@_current_validation_group[:name]}", *args, &block)
29
+ end
16
30
 
17
- @current_validation_group = group
18
- class_eval &block
19
- @current_validation_group = nil
31
+ def _define_group_validation_callbacks(group)
32
+ define_callbacks :"validate_#{group}", :scope => 'validate'
20
33
  end
21
34
 
22
35
  end
23
36
 
24
37
  module InstanceMethods
25
- def self.included(base)
26
- base.alias_method_chain :valid?, :groups
27
- base.class_eval do
28
- class << self
29
- if ActiveRecord::VERSION::MAJOR < 3
30
- alias_method_chain :validation_method, :groups
31
- else
32
- alias_method_chain :validate, :groups
33
- end
34
- end
38
+
39
+ def valid?(context=nil)
40
+ super
41
+ validation_groups.each do |group|
42
+ _run_group_validation_callbacks(group, context)
35
43
  end
44
+ errors.empty?
36
45
  end
37
46
 
38
47
  def groups_valid?(*groups)
48
+ options = groups.extract_options!
39
49
  errors.clear
40
50
  groups.each do |group|
41
51
  raise "Validation group '#{group}' not defined" unless validation_groups.include?(group)
42
- run_group_validation_callbacks group
52
+ _run_group_validation_callbacks(group, options[:context])
43
53
  end
44
54
  errors.empty?
45
55
  end
46
- alias group_valid? groups_valid?
56
+ alias_method :group_valid?, :groups_valid?
47
57
 
48
- end
58
+ def grouped_errors(context=nil)
59
+ original_errors = @errors.dup if @errors
60
+ @errors = nil
61
+ grouped = {}
49
62
 
50
- end
63
+ with_validation_context(context) do
64
+ _run_validate_callbacks
65
+ grouped[nil] = @errors
51
66
 
52
- ActiveRecord::Base.class_eval do
53
- extend GroupedValidations::ClassMethods
54
- class_inheritable_accessor :validation_groups
55
- end
67
+ validation_groups.each do |group|
68
+ @errors = nil
69
+ send(:"_run_validate_#{group}_callbacks")
70
+ grouped[group] = @errors
71
+ end
72
+ end
73
+ grouped.values.all?(&:empty?) ? {} : grouped
74
+ ensure
75
+ @errors = original_errors
76
+ end
77
+
78
+ def _run_group_validation_callbacks(group, context=nil)
79
+ with_validation_context(context) do
80
+ send(:"_run_validate_#{group}_callbacks")
81
+ end
82
+ end
56
83
 
57
- if ActiveRecord::VERSION::MAJOR < 3
58
- require 'grouped_validations/active_record'
59
- else
60
- require 'grouped_validations/active_model'
84
+ def with_validation_context(context)
85
+ context ||= (persisted? ? :update : :create)
86
+ current_context, self.validation_context = validation_context, context
87
+ yield
88
+ ensure
89
+ self.validation_context = current_context
90
+ end
91
+
92
+ end
61
93
  end
@@ -1,43 +1,34 @@
1
- module GroupedValidations
1
+ module ActiveModel
2
+ module Validations
2
3
 
3
- module ClassMethods
4
+ module ClassMethods
4
5
 
5
- def define_group_validation_callbacks(group)
6
- define_callbacks :"validate_#{group}", :terminator => "result == false", :scope => 'validate'
7
- end
6
+ def validation_group(group, options={}, &block)
7
+ raise "The validation_group method requires a block" unless block_given?
8
8
 
9
- def validate_with_groups(*args, &block)
10
- if @current_validation_group
11
- options = args.last
12
- if options.is_a?(Hash) && options.key?(:on)
13
- options[:if] = Array(options[:if])
14
- options[:if] << "self.validation_context == :#{options[:on]}"
9
+ unless include?(GroupedValidations)
10
+ include GroupedValidations
15
11
  end
16
- set_callback(:"validate_#{@current_validation_group}", *args, &block)
17
- else
18
- validate_without_groups(*args, &block)
19
- end
20
- end
21
12
 
22
- end
13
+ self.validation_groups += [ group ]
23
14
 
24
- module InstanceMethods
15
+ _define_group_validation_callbacks(group)
25
16
 
26
- def valid_with_groups?(context=nil)
27
- valid_without_groups?(context)
28
- (validation_groups || []).each do |group|
29
- run_group_validation_callbacks group
17
+ options[:name] = group
18
+
19
+ if block.arity == 1
20
+ @_current_validation_group = options.merge(:with_options => true)
21
+ with_options(options.except(:name)) do |config|
22
+ yield config
23
+ end
24
+ else
25
+ @_current_validation_group = options
26
+ yield
27
+ end
28
+ @_current_validation_group = nil
30
29
  end
31
- errors.empty?
32
- end
33
30
 
34
- def run_group_validation_callbacks(group)
35
- current_context, self.validation_context = validation_context, (new_record? ? :create : :update)
36
- send(:"_run_validate_#{group}_callbacks")
37
- ensure
38
- self.validation_context = current_context
39
31
  end
40
32
 
41
33
  end
42
-
43
34
  end
@@ -1,3 +1,3 @@
1
1
  module GroupedValidations
2
- VERSION = '0.2.2'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -1,6 +1,8 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe GroupedValidations do
4
+ let(:person) { Person.new }
5
+
4
6
  before do
5
7
  reset_class Person
6
8
  end
@@ -9,123 +11,242 @@ describe GroupedValidations do
9
11
  Person.should respond_to(:validation_group)
10
12
  end
11
13
 
12
- it "should not include instance methods by default" do
13
- ActiveRecord::Base.include?(GroupedValidations::InstanceMethods).should be_false
14
- end
14
+ describe ".validation_group" do
15
+ it "should store defined validation group names" do
16
+ Person.class_eval do
17
+ validation_group(:dummy) { }
18
+ end
19
+ Person.validation_groups.should == [:dummy]
20
+ end
15
21
 
16
- it "should store defined validation group names" do
17
- Person.validation_group(:dummy) { }
18
- Person.validation_groups.should == [:dummy]
19
- end
22
+ it "it should add group_valid? method which takes a group name param" do
23
+ Person.class_eval do
24
+ validation_group(:dummy) { }
25
+ end
26
+
27
+ person.group_valid?(:dummy)
28
+ end
20
29
 
21
- it "it should add group_valid? method which takes a group name param" do
22
- Person.validation_group(:dummy) { }
23
- p = Person.new
24
- p.group_valid?(:dummy)
25
- end
30
+ context "with options" do
31
+ context "as implicit block" do
32
+ it 'should pass options for group to validations' do
33
+ Person.class_eval do
34
+ validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do
35
+ validates_presence_of :first_name
36
+ end
37
+ end
38
+
39
+ person.group_valid?(:name)
40
+ person.should have(1).errors
41
+
42
+ person.last_name = 'smith'
43
+ person.group_valid?(:name)
44
+ person.should have(0).errors
45
+ end
46
+
47
+ it 'should not override explicit validation method options' do
48
+ Person.class_eval do
49
+ validation_group(:name, :if => lambda { true }) do
50
+ validates_presence_of :first_name, :if => lambda { false }
51
+ end
52
+ end
53
+
54
+ person.group_valid?(:name)
55
+ person.should have(0).errors
56
+ end
57
+ end
26
58
 
27
- it "should raise exception if valiation group not defined on group_valid check" do
28
- p = Person.new
29
- lambda { p.group_valid?(:dummy) }.should raise_exception
59
+ context "as block argument" do
60
+ it 'should pass options for group to validations' do
61
+ Person.class_eval do
62
+ validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do |options|
63
+ options.validates_presence_of :first_name
64
+ end
65
+ end
66
+
67
+ person.group_valid?(:name)
68
+ person.should have(1).errors
69
+
70
+ person.last_name = 'smith'
71
+ person.group_valid?(:name)
72
+ person.should have(0).errors
73
+ end
74
+
75
+ it 'should not override explicit options' do
76
+ Person.class_eval do
77
+ validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do |options|
78
+ options.validates_presence_of :first_name, :if => lambda { false }
79
+ end
80
+ end
81
+
82
+ person.group_valid?(:name)
83
+ person.should have(0).errors
84
+ end
85
+
86
+ it 'should not apply options to validations methods not using block argument' do
87
+ Person.class_eval do
88
+ validation_group(:name, :if => lambda { false }) do |options|
89
+ options.validates_presence_of :first_name
90
+ validates_presence_of :last_name
91
+ end
92
+ end
93
+
94
+ person.group_valid?(:name)
95
+ person.errors[:first_name].should be_empty
96
+ person.errors[:last_name].should_not be_empty
97
+ end
98
+ end
99
+ end
30
100
  end
31
101
 
32
- it "should run the validations defined inside the validation group" do
33
- Person.validation_group :name do
34
- validates_presence_of :first_name
35
- validates_presence_of :last_name
102
+ describe "#group_valid?" do
103
+ it "should run the validations defined inside the validation group" do
104
+ Person.class_eval do
105
+ validation_group :name do
106
+ validates_presence_of :first_name
107
+ validates_presence_of :last_name
108
+ end
109
+ end
110
+
111
+ person.group_valid?(:name)
112
+ person.should have(2).errors
113
+
114
+ person.first_name = 'Dave'
115
+ person.last_name = 'Smith'
116
+ person.group_valid?(:name)
117
+ person.should have(0).errors
36
118
  end
37
119
 
38
- p = Person.new
39
- p.group_valid?(:name)
40
- p.should have(2).errors
41
-
42
- p.first_name = 'Dave'
43
- p.last_name = 'Smith'
44
- p.group_valid?(:name)
45
- p.should have(0).errors
46
- end
120
+ it "should raise exception if valiation group not defined" do
121
+ expect { person.group_valid?(:dummy) }.should raise_exception
122
+ end
47
123
 
48
- it "should run all validation groups passed to groups_valid?" do
49
- Person.class_eval do
50
- validation_group :first_name_group do
51
- validates_presence_of :first_name
52
- end
53
- validation_group :last_name_group do
54
- validates_presence_of :last_name
124
+ it "should run all validation groups passed to groups_valid?" do
125
+ Person.class_eval do
126
+ validation_group :first_name_group do
127
+ validates_presence_of :first_name
128
+ end
129
+ validation_group :last_name_group do
130
+ validates_presence_of :last_name
131
+ end
55
132
  end
133
+
134
+ person.groups_valid?(:first_name_group, :last_name_group)
135
+ person.should have(2).errors
56
136
  end
57
137
 
58
- p = Person.new
59
- p.groups_valid?(:first_name_group, :last_name_group)
60
- p.should have(2).errors
61
- end
62
-
63
- it "should run all validation including groups when valid? method called" do
64
- Person.class_eval do
65
- validation_group :first_name_group do
66
- validates_presence_of :first_name
138
+ context "with validation context" do
139
+ it "should run only validations for explicit context" do
140
+ Person.class_eval do
141
+ validation_group :name do
142
+ validates_presence_of :last_name, :on => :update
143
+ end
144
+ end
145
+
146
+ person.persisted = false
147
+ person.last_name = nil
148
+ person.group_valid?(:name, :context => :create)
149
+ person.should have(0).errors
150
+
151
+ person.persisted = true
152
+ person.group_valid?(:name, :context => :update)
153
+ person.should have(1).errors
154
+
155
+ person.last_name = 'Smith'
156
+ person.group_valid?(:name)
157
+ person.should have(0).errors
67
158
  end
68
- validation_group :last_name_group do
69
- validates_presence_of :last_name
159
+
160
+ it "should run only validations for implicit model context" do
161
+ Person.class_eval do
162
+ validation_group :name do
163
+ validates_presence_of :first_name, :on => :create
164
+ end
165
+ end
166
+
167
+ person.persisted = false
168
+ person.group_valid?(:name)
169
+ person.should have(1).errors
170
+
171
+ person.first_name = 'Dave'
172
+ person.group_valid?(:name)
173
+ person.should have(0).errors
174
+
175
+ person.persisted = true
176
+ person.first_name = nil
177
+ person.group_valid?(:name)
178
+ person.should have(0).errors
70
179
  end
71
180
 
72
- validates_presence_of :sex
73
181
  end
182
+ end
74
183
 
75
- p = Person.new
76
- p.valid?
77
- p.should have(3).errors
184
+ describe "#valid?" do
185
+ it "should run all validation including groups when valid? method called" do
186
+ Person.class_eval do
187
+ validation_group :first_name_group do
188
+ validates_presence_of :first_name
189
+ end
190
+ validation_group :last_name_group do
191
+ validates_presence_of :last_name
192
+ end
193
+ validates_presence_of :sex
194
+ end
195
+
196
+ person.valid?
197
+ person.should have(3).errors
198
+ end
78
199
  end
79
200
 
80
- it "should respect :on => :create validation option" do
81
- Person.validation_group :name do
82
- validates_presence_of :first_name, :on => :create
201
+ describe "#grouped_errors" do
202
+ before do
203
+ Person.class_eval do
204
+ validation_group :first_name_group do
205
+ validates_presence_of :first_name
206
+ end
207
+ validation_group :last_name_group do
208
+ validates_presence_of :last_name
209
+ end
210
+ validates_presence_of :sex
211
+ end
83
212
  end
84
213
 
85
- p = Person.new
86
- p.group_valid?(:name)
87
- p.should have(1).errors
88
- p.first_name = 'Dave'
89
- p.group_valid?(:name)
90
- p.should have(0).errors
91
-
92
- p.save.should be_true
93
- p.first_name = nil
94
- p.group_valid?(:name)
95
- p.should have(0).errors
96
- end
214
+ it 'should return hash of error hashes with validation groups as keys' do
215
+ errors = person.grouped_errors
216
+ errors[:first_name_group].should == {:first_name => ["can't be blank"]}
217
+ errors[:last_name_group].should == {:last_name => ["can't be blank"]}
218
+ end
97
219
 
98
- it "should respect :on => :update validation option" do
99
- Person.validation_group :name do
100
- validates_presence_of :last_name, :on => :update
220
+ it 'should return hash of errors for validations outside a validation group, for nil key' do
221
+ errors = person.grouped_errors
222
+ errors[nil][:sex].should == ["can't be blank"]
101
223
  end
102
224
 
103
- p = Person.new
104
- p.last_name = nil
105
- p.group_valid?(:name)
106
- p.should have(0).errors
107
-
108
- p.save.should be_true
109
- p.group_valid?(:name)
110
- p.should have(1).errors
111
- p.last_name = 'Smith'
112
- p.group_valid?(:name)
113
- p.should have(0).errors
114
- end
225
+ it 'should be empty if no errors' do
226
+ person.first_name = 'Dave'
227
+ person.last_name = 'Smith'
228
+ person.sex = 'Male'
115
229
 
116
- it "should allow a validation group to appended with subsequent blocks" do
117
- Person.class_eval do
118
- validation_group :name do
119
- validates_presence_of :first_name
120
- end
121
- validation_group :name do
122
- validates_presence_of :last_name
123
- end
230
+ person.grouped_errors.should be_empty
124
231
  end
125
232
 
126
- p = Person.new
127
- p.group_valid?(:name)
128
- p.should have(2).errors
129
233
  end
130
234
 
235
+ # Can no longer be done. Unless I find a work around.
236
+ # it "should allow a validation group to appended with subsequent blocks" do
237
+ # Person.class_eval do
238
+ # validation_group :name do
239
+ # validates_presence_of :first_name
240
+ # end
241
+ # validation_group :name do
242
+ # validates_presence_of :last_name
243
+ # end
244
+ # end
245
+
246
+ #
247
+ # person.group_valid?(:name)
248
+ # puts person.errors.inspect
249
+ # person.should have(2).errors
250
+ # end
251
+
131
252
  end
data/spec/spec_helper.rb CHANGED
@@ -1,36 +1,32 @@
1
- $:.unshift File.expand_path(File.dirname(__FILE__) + '/lib')
2
- $:.unshift File.expand_path(File.dirname(__FILE__) + '/spec')
1
+ require 'rspec'
3
2
 
4
- require 'rubygems'
5
- require 'active_record'
6
- require 'active_support'
3
+ require 'active_support/all'
4
+ require 'active_model'
7
5
 
8
6
  require 'grouped_validations'
9
7
 
10
- ActiveRecord::Migration.verbose = false
11
- ActiveRecord::Base.establish_connection({:adapter => 'sqlite3', :database => ':memory:'})
8
+ class TestModel
9
+ include ActiveSupport::Callbacks
10
+ include ActiveModel::Validations
12
11
 
13
- ActiveRecord::Schema.define(:version => 1) do
14
- create_table :people, :force => true do |t|
15
- t.string :first_name
16
- t.string :last_name
17
- t.integer :sex
18
- end
12
+ attr_accessor :persisted, :first_name, :last_name, :sex
13
+ alias_method :persisted?, :persisted
19
14
  end
20
15
 
21
- class Person < ActiveRecord::Base
16
+ class Person < TestModel
22
17
  end
23
18
 
24
19
  module SpecHelper
25
20
  def reset_class(klass, &block)
21
+ superklass = klass.superclass
26
22
  name = klass.name.to_sym
27
23
  Object.send(:remove_const, name)
28
- Object.const_set(name, Class.new(ActiveRecord::Base))
24
+ Object.const_set(name, Class.new(superklass))
29
25
  new_klass = Object.const_get(name)
30
26
  new_klass.class_eval &block if block_given?
31
27
  end
32
28
  end
33
29
 
34
- Spec::Runner.configure do |config|
30
+ RSpec.configure do |config|
35
31
  config.include SpecHelper
36
32
  end
metadata CHANGED
@@ -2,12 +2,12 @@
2
2
  name: grouped_validations
3
3
  version: !ruby/object:Gem::Version
4
4
  hash: 19
5
- prerelease: false
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 2
10
- version: 0.2.2
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Adam Meehan
@@ -15,11 +15,11 @@ autorequire: grouped_validations
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-10 00:00:00 +10:00
18
+ date: 2011-03-29 00:00:00 +11:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
22
- description: Define validation groups in ActiveRecord for greater control over which validations to run.
22
+ description: Define validation groups in a model for greater control over which validations are run.
23
23
  email: adam.meehan@gmail.com
24
24
  executables: []
25
25
 
@@ -28,13 +28,16 @@ extensions: []
28
28
  extra_rdoc_files:
29
29
  - README.rdoc
30
30
  files:
31
+ - Gemfile
32
+ - Gemfile.lock
31
33
  - MIT-LICENSE
32
34
  - README.rdoc
33
35
  - Rakefile
36
+ - grouped_validations.gemspec
37
+ - init.rb
38
+ - lib/grouped_validations.rb
34
39
  - lib/grouped_validations/active_model.rb
35
- - lib/grouped_validations/active_record.rb
36
40
  - lib/grouped_validations/version.rb
37
- - lib/grouped_validations.rb
38
41
  - spec/grouped_validations_spec.rb
39
42
  - spec/spec_helper.rb
40
43
  has_rdoc: true
@@ -67,9 +70,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
70
  requirements: []
68
71
 
69
72
  rubyforge_project: grouped_validations
70
- rubygems_version: 1.3.7
73
+ rubygems_version: 1.5.2
71
74
  signing_key:
72
75
  specification_version: 3
73
- summary: Define validation groups in ActiveRecord for greater control over which validations to run.
74
- test_files: []
75
-
76
+ summary: Define validation groups in a model for greater control over which validations are run.
77
+ test_files:
78
+ - spec/grouped_validations_spec.rb
79
+ - spec/spec_helper.rb
@@ -1,47 +0,0 @@
1
- module GroupedValidations
2
-
3
- module ClassMethods
4
-
5
- def define_group_validation_callbacks(group)
6
- base_name = :"validate_#{group}"
7
- define_callbacks base_name, :"#{base_name}_on_create", :"#{base_name}_on_update"
8
- end
9
-
10
- def validation_method_with_groups(on)
11
- if @current_validation_group
12
- base_name = :"validate_#{@current_validation_group}"
13
- case on
14
- when :save then base_name
15
- when :create then :"#{base_name}_on_create"
16
- when :update then :"#{base_name}_on_update"
17
- end
18
- else
19
- validation_method_without_groups on
20
- end
21
- end
22
-
23
- end
24
-
25
- module InstanceMethods
26
-
27
- def valid_with_groups?
28
- valid_without_groups?
29
- (validation_groups || []).each do |group|
30
- run_group_validation_callbacks group
31
- end
32
- errors.empty?
33
- end
34
-
35
- def run_group_validation_callbacks(group)
36
- base_name = :"validate_#{group}"
37
- run_callbacks(base_name)
38
- if new_record?
39
- run_callbacks(:"#{base_name}_on_create")
40
- else
41
- run_callbacks(:"#{base_name}_on_update")
42
- end
43
- end
44
-
45
- end
46
-
47
- end