From ffb5467ba1671c7606b1489e92099c6708449e07 Mon Sep 17 00:00:00 2001 From: Adam Meehan Date: Fri, 4 Feb 2011 06:18:44 +1100 Subject: [PATCH] Allow block arg to pass options into block using with_options --- lib/grouped_validations.rb | 26 +++--- lib/grouped_validations/active_model.rb | 13 ++- spec/grouped_validations_spec.rb | 101 ++++++++++++++++++------ spec/spec_helper.rb | 2 +- 4 files changed, 104 insertions(+), 38 deletions(-) diff --git a/lib/grouped_validations.rb b/lib/grouped_validations.rb index 097fb0f..7d3ed68 100644 --- a/lib/grouped_validations.rb +++ b/lib/grouped_validations.rb @@ -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) diff --git a/lib/grouped_validations/active_model.rb b/lib/grouped_validations/active_model.rb index 5baf64f..11c17af 100644 --- a/lib/grouped_validations/active_model.rb +++ b/lib/grouped_validations/active_model.rb @@ -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 diff --git a/spec/grouped_validations_spec.rb b/spec/grouped_validations_spec.rb index 6ad41c9..6136163 100644 --- a/spec/grouped_validations_spec.rb +++ b/spec/grouped_validations_spec.rb @@ -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) @@ -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 @@ -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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 90f41a3..3b5c82f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,6 @@ require 'rspec' -require 'active_support' +require 'active_support/all' require 'active_model' require 'grouped_validations'