grouped_validations 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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