validation_group 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ pkg
3
+ rdoc
4
+ coverage
5
+ *.log
File without changes
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,33 @@
1
+ ValidationGroup
2
+ ===============
3
+
4
+ When doing multipage forms that spread a models fields over several pages, validation becomes more difficult. We would like to validate each step of the form, however, the rails validation run validation on all the fields. This plugin enables you to define validation groups with certain fields, and then only run validation on those groups.
5
+
6
+ Version: Rails 3. To use on Rails 2.x versions, use forked copy from https://github.com/jeffp/validationgroup
7
+
8
+ To install:
9
+
10
+ Add to your Gemfile:
11
+
12
+ gem 'validation_group', :git=>'git://github.com/akira/validationgroup.git'
13
+
14
+ Example
15
+ =======
16
+
17
+ class User < ActiveRecord::Base
18
+ validates_presence_of :name, :description, :address, :email
19
+
20
+ validation_group :step1, :fields=>[:name, :description]
21
+ validation_group :step2, :fields=>[:address]
22
+ end
23
+
24
+ This will run validation on :step1 fields
25
+ @user = User.new
26
+ @user.enable_validation_group :step1
27
+ @user.valid?
28
+
29
+ You can later disable validation groups by calling:
30
+ @user.disable_validation_group
31
+
32
+
33
+ Copyright (c) 2007 Alex Kira, released under the MIT license
@@ -0,0 +1,55 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rubygems/package_task'
4
+ require 'rdoc/task'
5
+
6
+ spec = Gem::Specification.new do |s|
7
+ s.name = 'validation_group'
8
+ s.version = '0.1.3'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.description = 'Validation groups for ActiveRecord'
11
+ s.summary = 'Validation groups for ActiveRecord'
12
+
13
+ s.files = FileList['{lib,test,tasks}/**/*'] + %w(CHANGELOG.rdoc init.rb install.rb uninstall.rb MIT-LICENSE Rakefile README .gitignore) - FileList['**/*.log']
14
+ s.require_path = 'lib'
15
+ s.has_rdoc = true
16
+ s.test_files = Dir['test/*_test.rb']
17
+
18
+ s.author = 'Alex Kira'
19
+ s.email = ''
20
+ s.homepage = 'http://github.com/akira/validationgroup/tree/master'
21
+ end
22
+
23
+ desc 'Default: run unit tests.'
24
+ task :default => :test
25
+
26
+ desc 'Test the validation_group plugin.'
27
+ Rake::TestTask.new(:test) do |t|
28
+ t.libs << 'lib'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = true
31
+ end
32
+
33
+ desc 'Generate documentation for the validation_group plugin.'
34
+ RDoc::Task.new(:rdoc) do |rdoc|
35
+ rdoc.rdoc_dir = 'rdoc'
36
+ rdoc.title = 'ValidationGroup'
37
+ rdoc.options << '--line-numbers' << '--inline-source'
38
+ rdoc.rdoc_files.include('README', 'CHANGELOG.rdoc', 'MIT-LICENSE')
39
+ rdoc.rdoc_files.include('lib/**/*.rb')
40
+ end
41
+
42
+ desc 'Generate a gemspec file.'
43
+ task :gemspec do
44
+ File.open("#{spec.name}.gemspec", 'w') do |f|
45
+ f.write spec.to_ruby
46
+ end
47
+ end
48
+
49
+ Gem::PackageTask.new(spec) do |p|
50
+ p.gem_spec = spec
51
+ p.need_tar = true
52
+ p.need_zip = true
53
+ end
54
+
55
+ Dir['tasks/**/*.rake'].each {|rake| load rake}
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'validation_group'
2
+
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,122 @@
1
+ module ValidationGroup
2
+ module ActiveRecord
3
+ module ActsMethods # extends ActiveRecord::Base
4
+ def self.extended(base)
5
+ # Add class accessor which is shared between all models and stores
6
+ # validation groups defined for each model
7
+ base.class_eval do
8
+ cattr_accessor :validation_group_classes
9
+ self.validation_group_classes = {}
10
+
11
+ def self.validation_group_order; @validation_group_order; end
12
+ def self.validation_groups(all_classes = false)
13
+ return (self.validation_group_classes[self] || {}) unless all_classes
14
+ klasses = ValidationGroup::Util.current_and_ancestors(self).reverse
15
+ returning Hash.new do |hash|
16
+ klasses.each do |klass|
17
+ hash.merge! self.validation_group_classes[klass]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ def validation_group(name, options={})
25
+ self_groups = (self.validation_group_classes[self] ||= {})
26
+ self_groups[name.to_sym] = options[:fields] || []
27
+ # jeffp: capture the declaration order for this class only (no
28
+ # superclasses)
29
+ @validation_group_order ||= []
30
+ @validation_group_order << name.to_sym
31
+
32
+ unless included_modules.include?(InstanceMethods)
33
+ # jeffp: added reader for current_validation_fields
34
+ attr_reader :current_validation_group, :current_validation_fields
35
+ include InstanceMethods
36
+ # jeffp: add valid?(group = nil), see definition below
37
+ alias_method_chain :valid?, :validation_group
38
+ end
39
+ end
40
+ end
41
+
42
+ module InstanceMethods # included in every model which calls validation_group
43
+
44
+ def enable_validation_group(group)
45
+ # Check if given validation group is defined for current class or one of
46
+ # its ancestors
47
+ group_classes = self.class.validation_group_classes
48
+ found = ValidationGroup::Util.current_and_ancestors(self.class).
49
+ find do |klass|
50
+ group_classes[klass] && group_classes[klass].include?(group)
51
+ end
52
+ if found
53
+ @current_validation_group = group
54
+ # jeffp: capture current fields for performance optimization
55
+ @current_validation_fields = group_classes[found][group]
56
+ else
57
+ raise ArgumentError, "No validation group of name :#{group}"
58
+ end
59
+ end
60
+
61
+ def disable_validation_group
62
+ @current_validation_group = nil
63
+ # jeffp: delete fields
64
+ @current_validation_fields = nil
65
+ end
66
+
67
+ # jeffp: optimizer for someone writing custom :validate method -- no need
68
+ # to validate fields outside the current validation group note: could also
69
+ # use in validation modules to improve performance
70
+ def should_validate?(attribute)
71
+ !self.validation_group_enabled? || (@current_validation_fields && @current_validation_fields.include?(attribute.to_sym))
72
+ end
73
+
74
+ def validation_group_enabled?
75
+ respond_to?(:current_validation_group) && !current_validation_group.nil?
76
+ end
77
+
78
+ # eliminates need to use :enable_validation_group before :valid? call --
79
+ # nice
80
+ def valid_with_validation_group?(group=nil)
81
+ self.enable_validation_group(group) if group
82
+ valid_without_validation_group?
83
+ end
84
+ end
85
+
86
+ module Errors # included in ActiveRecord::Errors
87
+ def add_with_validation_group(attribute,
88
+ msg = nil, *args,
89
+ &block)
90
+ # jeffp: setting @current_validation_fields and use of should_validate? optimizes code
91
+ add_error = @base.respond_to?(:should_validate?) ? @base.should_validate?(attribute.to_sym) : true
92
+ add_without_validation_group(attribute, msg, *args, &block) if add_error
93
+ end
94
+
95
+ def self.included(base) #:nodoc:
96
+ base.class_eval do
97
+ alias_method_chain :add, :validation_group
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ module Util
104
+ # Return array consisting of current and its superclasses down to and
105
+ # including base_class.
106
+ def self.current_and_ancestors(current)
107
+ [].tap do |klasses|
108
+ klasses << current
109
+ root = current.base_class
110
+ until current == root
111
+ current = current.superclass
112
+ klasses << current
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ # jeffp: moved from init.rb for gemification purposes --
120
+ # require 'validation_group' loads everything now, init.rb requires 'validation_group' only
121
+ ActiveRecord::Base.send(:extend, ValidationGroup::ActiveRecord::ActsMethods)
122
+ ActiveModel::Errors.send :include, ValidationGroup::ActiveRecord::Errors
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :validation_group do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,18 @@
1
+ sqlite:
2
+ :adapter: sqlite
3
+ :dbfile: validation_group_plugin.sqlite.db
4
+ sqlite3:
5
+ :adapter: sqlite3
6
+ :dbfile: validation_group_plugin.sqlite3.db
7
+ postgresql:
8
+ :adapter: postgresql
9
+ :username: postgres
10
+ :password: postgres
11
+ :database: validation_group_plugin_test
12
+ :min_messages: ERROR
13
+ mysql:
14
+ :adapter: mysql
15
+ :host: localhost
16
+ :username: root
17
+ :password:
18
+ :database: validation_group_plugin_test
@@ -0,0 +1,12 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :validation_group_models, :force => true do |t|
3
+ t.column :name, :string, :limit => 255
4
+ t.column :description, :string, :limit => 255
5
+ t.column :address, :string, :limit => 255
6
+ t.column :email, :string, :limit => 255
7
+ end
8
+
9
+ create_table :plain_models, :force => true do |t|
10
+ t.column :name, :string, :limit => 255
11
+ end
12
+ end
@@ -0,0 +1,54 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+
3
+ require 'rubygems'
4
+
5
+ gem 'activerecord', ENV['AR_VERSION'] ? "=#{ENV['AR_VERSION']}" : '>=2.1.0'
6
+ require 'active_record'
7
+ require 'test/unit'
8
+ require 'validation_group'
9
+
10
+ # jeffp: removed fixture loading code - unnecessary
11
+ # jeffp: removed environment.rb reference for gemification purposes
12
+ # jeffp: added code to test in sqlite memory database - speedy tests
13
+
14
+ db_adapter = ENV['DB'] || begin
15
+ require 'rubygems'
16
+ require 'sqlite'
17
+ 'sqlite'
18
+ rescue MissingSourceFile
19
+ begin
20
+ require 'sqlite3'
21
+ 'sqlite3'
22
+ rescue MissingSourceFile
23
+ end
24
+ end
25
+
26
+ if db_adapter.nil?
27
+ raise "No DB Adapter selected. Pass the DB= to pick one, or install Sqlite or Sqlite3."
28
+ end
29
+
30
+ ActiveRecord::Base.establish_connection({'adapter' => db_adapter, 'database' => ':memory:'})
31
+ #ActiveRecord::Base.logger = Logger.new("#{File.dirname(__FILE__)}/active_record.log")
32
+
33
+ connection = ActiveRecord::Base.connection
34
+ connection.create_table(:validation_group_models, :force=>true) do |t|
35
+ t.string :name
36
+ t.string :description
37
+ t.string :address
38
+ t.string :email
39
+ end
40
+ connection.create_table(:validation_group_models, :force=>true) do |t|
41
+ t.string :name
42
+ t.string :description
43
+ t.string :address
44
+ t.string :email
45
+ end
46
+ connection.create_table(:plain_models, :force=>true) do |t|
47
+ t.string :name
48
+ end
49
+
50
+ class User < ActiveRecord::Base
51
+ validation_group :step1, :fields=>[:first_name, :last_name]
52
+ validation_group :step2, :fields=>[:username]
53
+ end
54
+
@@ -0,0 +1,140 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
2
+
3
+ class ValidationGroupModel < ActiveRecord::Base
4
+ validates_presence_of :name, :description, :address, :email
5
+
6
+ validation_group :step1, :fields=>[:name, :description]
7
+ validation_group :step2, :fields=>[:address]
8
+ end
9
+
10
+ class PlainModel < ActiveRecord::Base
11
+ validates_presence_of :name
12
+ end
13
+
14
+ class ValidationGroupTest < Test::Unit::TestCase
15
+ def test_validation_group_names_appear_in_order
16
+ order = ValidationGroupModel.validation_group_order
17
+ assert_not_nil order
18
+ assert_equal 2, order.size
19
+ assert_equal :step1, order[0]
20
+ assert_equal :step2, order[1]
21
+ end
22
+
23
+ def test_validation_group_fields_for_names
24
+ names = ValidationGroupModel.validation_group_order
25
+ groups = ValidationGroupModel.validation_groups
26
+ assert_not_nil groups
27
+ fields = groups[names[0]]
28
+ assert_equal 2, fields.size
29
+ assert fields.include?(:name)
30
+ assert fields.include?(:description)
31
+ fields = groups[names[1]]
32
+ assert_equal 1, fields.size
33
+ assert fields.include?(:address)
34
+ end
35
+
36
+ def test_validation_no_groups_fail
37
+ @model = ValidationGroupModel.new
38
+ assert !@model.valid?
39
+ assert_equal 4, @model.errors.size
40
+ end
41
+
42
+ def test_validation_group1_fail
43
+ @model = ValidationGroupModel.new
44
+ @model.enable_validation_group :step1
45
+ assert !@model.valid?
46
+ assert_equal 2, @model.errors.size
47
+ end
48
+
49
+ def test_validation_group1_add_error
50
+ @model = ValidationGroupModel.new(:name=>"Name", :description=>"Description")
51
+ @model.enable_validation_group :step1
52
+ @model.errors.add(:name, "Name is invalid")
53
+ assert !@model.errors.blank?
54
+ end
55
+
56
+ def test_validation_group1_add_error_empty_msg
57
+ @model = ValidationGroupModel.new(:name=>"Name", :description=>"Description")
58
+ @model.enable_validation_group :step1
59
+ @model.errors.add(:name)
60
+ assert !@model.errors.blank?
61
+ end
62
+
63
+ def test_validation_group1_pass
64
+ @model = ValidationGroupModel.new(:name=>"Name", :description=>"Description")
65
+ @model.enable_validation_group :step1
66
+ assert @model.valid?
67
+ assert_equal 0, @model.errors.size
68
+ @model.save!
69
+ end
70
+
71
+ def test_validation_group2_fail
72
+ @model = ValidationGroupModel.new
73
+ @model.enable_validation_group :step2
74
+ assert !@model.valid?
75
+ assert_equal 1, @model.errors.size
76
+ end
77
+
78
+ def test_validation_clear_group_fail
79
+ @model = ValidationGroupModel.new
80
+ @model.enable_validation_group :step1
81
+ assert !@model.valid?
82
+ assert_equal 2, @model.errors.size
83
+ @model.disable_validation_group
84
+ assert !@model.valid?
85
+ assert_equal 4, @model.errors.size
86
+ end
87
+
88
+ def test_validation_group_invalid
89
+ @model = ValidationGroupModel.new
90
+ assert_raise ArgumentError do
91
+ @model.enable_validation_group :invalid
92
+ end
93
+ end
94
+
95
+ def test_should_validate_no_groups
96
+ @model = ValidationGroupModel.new
97
+ assert @model.should_validate?(:name)
98
+ assert @model.should_validate?(:description)
99
+ assert @model.should_validate?(:address)
100
+ assert @model.should_validate?(:email)
101
+ end
102
+
103
+ def test_should_validate_group1
104
+ @model = ValidationGroupModel.new
105
+ @model.enable_validation_group(:step1)
106
+ assert @model.should_validate?(:name)
107
+ assert @model.should_validate?(:description)
108
+ assert !@model.should_validate?(:address)
109
+ assert !@model.should_validate?(:email)
110
+ end
111
+
112
+ def test_valid_query_sets_current
113
+ @model = ValidationGroupModel.new
114
+ @model.valid?(:step2)
115
+ assert_equal :step2, @model.current_validation_group
116
+ @model.valid?(:step1)
117
+ assert_equal :step1, @model.current_validation_group
118
+ end
119
+
120
+ def test_valid_group1_fails
121
+ @model = ValidationGroupModel.new
122
+ assert !@model.valid?(:step1)
123
+ end
124
+
125
+ def test_valid_group1_passes_and_group2_fails_then_passes
126
+ @model = ValidationGroupModel.new
127
+ @model.name = 'MyModel'
128
+ @model.description = 'My model'
129
+ assert @model.valid?(:step1)
130
+ assert !@model.valid?(:step2)
131
+ @model.address = 'uri:my_model'
132
+ assert @model.valid?
133
+ end
134
+
135
+ def test_validation_for_models_without_validation_group
136
+ @model = PlainModel.new
137
+ assert !@model.valid?
138
+ assert_equal 1, @model.errors.size
139
+ end
140
+ end
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: validation_group
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.3
6
+ platform: ruby
7
+ authors:
8
+ - Alex Kira
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-02-06 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description: Validation groups for ActiveRecord
17
+ email: ""
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/validation_group.rb
26
+ - test/database.yml
27
+ - test/schema.rb
28
+ - test/test_helper.rb
29
+ - test/validation_group_test.rb
30
+ - tasks/validation_group_tasks.rake
31
+ - CHANGELOG.rdoc
32
+ - init.rb
33
+ - install.rb
34
+ - uninstall.rb
35
+ - MIT-LICENSE
36
+ - Rakefile
37
+ - README
38
+ - .gitignore
39
+ homepage: http://github.com/akira/validationgroup/tree/master
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.8.15
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Validation groups for ActiveRecord
66
+ test_files:
67
+ - test/validation_group_test.rb