Skip to content

Commit

Permalink
changes for wizardly integration and gemification, test changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffp committed Aug 4, 2009
1 parent 8d97699 commit fc51a63
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 32 deletions.
62 changes: 38 additions & 24 deletions lib/validation_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,31 @@ def self.extended(base)
cattr_accessor :validation_group_classes
self.validation_group_classes = {}

def self.validation_group_names; @validation_group_names; end
def self.validation_groups
self.validation_group_classes[self] || {}
def self.validation_group_order; @validation_group_order; end
def self.validation_groups(all_classes = false)
return (self.validation_group_classes[self] || {}) unless all_classes
klasses = ValidationGroup::Util.current_and_ancestors(self).reverse
returning Hash.new do |hash|
klasses.each do |klass|
hash.merge! self.validation_group_classes[klass]
end
end
end
end
end

def validation_group(name, options={})
self_groups = (self.validation_group_classes[self] ||= {})
self_groups[name.to_sym] = options[:fields] || []
@validation_group_names ||= []
@validation_group_names << name.to_sym
#jeffp: capture the declaration order for this class only (no superclasses)
@validation_group_order ||= []
@validation_group_order << name.to_sym

unless included_modules.include?(InstanceMethods)
attr_reader :current_validation_group
#jeffp: added reader for current_validation_fields
attr_reader :current_validation_group, :current_validation_fields
include InstanceMethods
#jeffp: add valid?(group = nil), see definition below
alias_method_chain :valid?, :validation_group
end
end
Expand All @@ -36,25 +45,35 @@ def enable_validation_group(group)
# or one of its ancestors
group_classes = self.class.validation_group_classes
found = ValidationGroup::Util.current_and_ancestors(self.class).
find do |klass|
group_classes[klass] &&
group_classes[klass].include?(group)
end
find do |klass|
group_classes[klass] && group_classes[klass].include?(group)
end
if found
@current_validation_group = group
#jeffp: capture current fields for performance optimization
@current_validation_fields = group_classes[found][group]
else
raise ArgumentError, "No validation group of name #{group}"
raise ArgumentError, "No validation group of name :#{group}"
end
end

def disable_validation_group
@current_validation_group = nil
#jeffp: delete fields
@current_validation_fields = nil
end

#jeffp: optimizer for someone writing custom :validate method -- no need to validate fields outside the current validation group
# note: could also use in validation modules to improve performance
def should_validate?(attribute)
@current_validation_fields && @current_validation_fields.include?(attribute.to_sym)
end

def validation_group_enabled?
respond_to?(:current_validation_group) && !current_validation_group.nil?
end

#eliminates need to use :enable_validation_group before :valid? call -- nice
def valid_with_validation_group?(group=nil)
self.enable_validation_group(group) if group
valid_without_validation_group?
Expand All @@ -67,18 +86,12 @@ def add_with_validation_group(attribute,
&block)
add_error = true
if @base.validation_group_enabled?
current_group = @base.current_validation_group
found = ValidationGroup::Util.current_and_ancestors(@base.class).
find do |klass|
klasses = klass.validation_group_classes
klasses[klass] && klasses[klass][current_group] &&
klasses[klass][current_group].include?(attribute)
end
add_error = false unless found
end
add_without_validation_group(attribute, msg, *args,&block) if add_error
end

#jeffp: use of should_validate?, note optimized with @current_validation_fields -- compare to previous code
add_error = false unless @base.should_validate?(attribute.to_sym)
end
add_without_validation_group(attribute, msg, *args, &block) if add_error
end

def self.included(base) #:nodoc:
base.class_eval do
alias_method_chain :add, :validation_group
Expand All @@ -88,7 +101,7 @@ def self.included(base) #:nodoc:
end

module Util
# Return array of consisting of current and its superclasses
# Return array consisting of current and its superclasses
# down to and including base_class.
def self.current_and_ancestors(current)
returning [] do |klasses|
Expand All @@ -103,5 +116,6 @@ def self.current_and_ancestors(current)
end
end

#jeffp: moved from init.rb for gemification purposes -- require 'validation_group' loads everything
ActiveRecord::Base.send(:extend, ValidationGroup::ActiveRecord::ActsMethods)
ActiveRecord::Errors.send :include, ValidationGroup::ActiveRecord::Errors
32 changes: 31 additions & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,27 @@
require 'test/unit'
require 'validation_group'

ActiveRecord::Base.establish_connection({'adapter' => 'sqlite3', 'database' => ':memory:'})
#jeffp: removed fixture loading code - unnecessary
#jeffp: removed environment.rb reference for gemification purposes
#jeffp: added code to test in sqlite memory database!

db_adapter = ENV['DB'] || begin
require 'rubygems'
require 'sqlite'
'sqlite'
rescue MissingSourceFile
begin
require 'sqlite3'
'sqlite3'
rescue MissingSourceFile
end
end

if db_adapter.nil?
raise "No DB Adapter selected. Pass the DB= to pick one, or install Sqlite or Sqlite3."
end

ActiveRecord::Base.establish_connection({'adapter' => db_adapter, 'database' => ':memory:'})
ActiveRecord::Base.logger = Logger.new("#{File.dirname(__FILE__)}/active_record.log")

connection = ActiveRecord::Base.connection
Expand All @@ -17,4 +37,14 @@
t.string :address
t.string :email
end
connection.create_table(:user, :force=>true) do |t|
t.string :first_name
t.string :last_name
t.string :username
end

class User < ActiveRecord::Base
validation_group :step1, :fields=>[:first_name, :last_name]
validation_group :step2, :fields=>[:username]
end

12 changes: 6 additions & 6 deletions test/validation_group_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ class ValidationGroupModel < ActiveRecord::Base

class ValidationGroupTest < Test::Unit::TestCase
def test_validation_group_names_appear_in_order
names = ValidationGroupModel.validation_group_names
assert_not_nil names
assert_equal 2, names.size
assert_equal :step1, names[0]
assert_equal :step2, names[1]
order = ValidationGroupModel.validation_group_order
assert_not_nil order
assert_equal 2, order.size
assert_equal :step1, order[0]
assert_equal :step2, order[1]
end

def test_validation_group_fields_for_names
names = ValidationGroupModel.validation_group_names
names = ValidationGroupModel.validation_group_order
groups = ValidationGroupModel.validation_groups
assert_not_nil groups
fields = groups[names[0]]
Expand Down
2 changes: 1 addition & 1 deletion validation_group.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Gem::Specification.new do |s|

s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Alex Kira"]
s.date = %q{2009-07-27}
s.date = %q{2009-07-28}
s.description = %q{Validation groups for ActiveRecord}
s.email = %q{}
s.files = ["lib/validation_group.rb", "test/test_helper.rb", "test/validation_group_test.rb", "tasks/validation_group_tasks.rake", "CHANGELOG.rdoc", "init.rb", "install.rb", "uninstall.rb", "MIT-LICENSE", "Rakefile", "README", ".gitignore"]
Expand Down

0 comments on commit fc51a63

Please sign in to comment.