Navigation Menu

Skip to content

Commit

Permalink
Allow block arg to pass options into block using with_options
Browse files Browse the repository at this point in the history
  • Loading branch information
adzap committed Feb 3, 2011
1 parent 98b9a7b commit ffb5467
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 38 deletions.
26 changes: 14 additions & 12 deletions lib/grouped_validations.rb
Expand Up @@ -6,24 +6,26 @@ module GroupedValidations

included do
class_attribute :validation_groups
self.validation_groups = []
end

module ClassMethods

def validate(*args, &block)
if @current_validation_group
options = args.extract_options!.dup
options.reverse_merge!(@current_validation_group.except(:name))
if options.key?(:on)
options = options.dup
options[:if] = Array.wrap(options[:if])
options[:if] << "validation_context == :#{options[:on]}"
end
args << options
set_callback(:"validate_#{@current_validation_group[:name]}", *args, &block)
else
super
return super unless @_current_validation_group

options = args.extract_options!.dup
unless @_current_validation_group[:with_options]
options.reverse_merge!(@_current_validation_group.except(:name))
end

if options.key?(:on)
options = options.dup
options[:if] = Array.wrap(options[:if])
options[:if] << "validation_context == :#{options[:on]}"
end
args << options
set_callback(:"validate_#{@_current_validation_group[:name]}", *args, &block)
end

def _define_group_validation_callbacks(group)
Expand Down
13 changes: 10 additions & 3 deletions lib/grouped_validations/active_model.rb
Expand Up @@ -17,9 +17,16 @@ def validation_group(group, options={}, &block)

options[:name] = group

@current_validation_group = options
class_eval &block
@current_validation_group = nil
if block.arity == 1
@_current_validation_group = options.merge(:with_options => true)
with_options(options) do |config|
yield config
end
else
@_current_validation_group = options
yield
end
@_current_validation_group = nil
end

end
Expand Down
101 changes: 79 additions & 22 deletions spec/grouped_validations_spec.rb
Expand Up @@ -13,46 +13,99 @@

describe ".validation_group" do
it "should store defined validation group names" do
Person.validation_group(:dummy) { }
Person.class_eval do
validation_group(:dummy) { }
end
Person.validation_groups.should == [:dummy]
end

it "it should add group_valid? method which takes a group name param" do
Person.validation_group(:dummy) { }
Person.class_eval do
validation_group(:dummy) { }
end

person.group_valid?(:dummy)
end

context "with options" do
it 'should pass option for group to validations' do
Person.validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do
validates_presence_of :first_name
context "as implicit block" do
it 'should pass options for group to validations' do
Person.class_eval do
validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do
validates_presence_of :first_name
end
end

person.group_valid?(:name)
person.should have(1).errors

person.last_name = 'smith'
person.group_valid?(:name)
person.should have(0).errors
end

person.group_valid?(:name)
person.should have(1).errors
it 'should not override explicit validation method options' do
Person.class_eval do
validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do
validates_presence_of :first_name, :if => lambda { false }
end
end

person.last_name = 'Smith'
person.group_valid?(:name)
person.should have(0).errors
person.group_valid?(:name)
person.should have(0).errors
end
end

it 'should not override explicit validation method options' do
Person.validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do
validates_presence_of :first_name, :if => lambda { false }
context "as block argument" do
it 'should pass options for group to validations' do
Person.class_eval do
validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do |options|
options.validates_presence_of :first_name
end
end

person.group_valid?(:name)
person.should have(1).errors

person.last_name = 'smith'
person.group_valid?(:name)
person.should have(0).errors
end

person.group_valid?(:name)
person.should have(0).errors
it 'should not override explicit options' do
Person.class_eval do
validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do |options|
options.validates_presence_of :first_name, :if => lambda { false }
end
end

person.group_valid?(:name)
person.should have(0).errors
end

it 'should not apply options to validations methods not using block argument' do
Person.class_eval do
validation_group(:name, :if => lambda {|r| false }) do |options|
options.validates_presence_of :first_name
validates_presence_of :last_name
end
end

person.group_valid?(:name)
person.errors[:first_name].should be_empty
person.errors[:last_name].should_not be_empty
end
end
end
end

describe "#group_valid?" do
it "should run the validations defined inside the validation group" do
Person.validation_group :name do
validates_presence_of :first_name
validates_presence_of :last_name
Person.class_eval do
validation_group :name do
validates_presence_of :first_name
validates_presence_of :last_name
end
end

person.group_valid?(:name)
Expand Down Expand Up @@ -84,8 +137,10 @@

context "with validation context" do
it "should run only validations for explicit context" do
Person.validation_group :name do
validates_presence_of :last_name, :on => :update
Person.class_eval do
validation_group :name do
validates_presence_of :last_name, :on => :update
end
end

person.persisted = false
Expand All @@ -103,8 +158,10 @@
end

it "should run only validations for implicit model context" do
Person.validation_group :name do
validates_presence_of :first_name, :on => :create
Person.class_eval do
validation_group :name do
validates_presence_of :first_name, :on => :create
end
end

person.persisted = false
Expand Down
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
@@ -1,6 +1,6 @@
require 'rspec'

require 'active_support'
require 'active_support/all'
require 'active_model'

require 'grouped_validations'
Expand Down

0 comments on commit ffb5467

Please sign in to comment.