diff options
-rw-r--r-- | activerecord/CHANGELOG | 8 | ||||
-rwxr-xr-x | activerecord/lib/active_record/validations.rb | 6 | ||||
-rwxr-xr-x | activerecord/test/validations_test.rb | 19 |
3 files changed, 28 insertions, 5 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index e2dfa77e0b..d05ecfbe31 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,13 @@ *SVN* +* Added that validates_* now accept blocks to perform validations #618 [Tim Bates]. Example: + + class Person < ActiveRecord::Base + validate { |person| person.errors.add("title", "will never be valid") if SHOULD_NEVER_BE_VALID } + end + +* Addded validation for validate all the associated objects before declaring failure with validates_associated #618 [Tim Bates] + * Added keyword-style approach to defining the custom relational bindings #545 [Jamis Buck]. Example: class Project < ActiveRecord::Base diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 1e5d4287b0..a7811e50ac 100755 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -51,7 +51,7 @@ module ActiveRecord alias_method :update_attribute_without_validation_skipping, :update_attribute alias_method :update_attribute, :update_attribute_with_validation_skipping - VALIDATIONS.each { |vd| base.class_eval("def self.#{vd}(*methods) write_inheritable_array(\"#{vd}\", methods - (read_inheritable_attribute(\"#{vd}\") || [])) end") } + VALIDATIONS.each { |vd| base.class_eval("def self.#{vd}(*methods, &block) write_inheritable_array(\"#{vd}\", methods + [block].compact - (read_inheritable_attribute(\"#{vd}\") || [])) end") } end base.extend(ClassMethods) @@ -300,7 +300,7 @@ module ActiveRecord for attr_name in attr_names class_eval(%(#{validation_method(configuration[:on])} %{ errors.add("#{attr_name}", "#{configuration[:message]}") unless - (#{attr_name}.is_a?(Array) ? #{attr_name} : [#{attr_name}]).inject(true){ |memo, record| memo and (record.nil? or record.valid?) } + (#{attr_name}.is_a?(Array) ? #{attr_name} : [#{attr_name}]).inject(true){ |memo, record| (record.nil? or record.valid?) and memo } })) end end @@ -378,7 +378,7 @@ module ActiveRecord eval(validation, binding) elsif validation_block?(validation) validation.call(self) - elsif filter_class?(validation, validation_method) + elsif validation_class?(validation, validation_method) validation.send(validation_method, self) else raise( diff --git a/activerecord/test/validations_test.rb b/activerecord/test/validations_test.rb index 052cf3d6ca..7ac93b43fb 100755 --- a/activerecord/test/validations_test.rb +++ b/activerecord/test/validations_test.rb @@ -392,10 +392,12 @@ class ValidationsTest < Test::Unit::TestCase def test_validates_associated_many Topic.validates_associated( :replies ) t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - t.replies << [r = Reply.create("title" => "A reply"), Reply.create("title" => "Another reply", "content" => "with content!")] + t.replies << [r = Reply.create("title" => "A reply"), r2 = Reply.create("title" => "Another reply")] assert !t.valid? assert t.errors.on(:replies) - r.content = "non-empty" + assert_equal 1, r.errors.count # make sure all associated objects have been validated + assert_equal 1, r2.errors.count + r.content = r2.content = "non-empty" assert t.valid? end @@ -410,6 +412,19 @@ class ValidationsTest < Test::Unit::TestCase assert r.valid? end + def test_validate_block + Topic.validate { |topic| topic.errors.add("title", "will never be valid") } + t = Topic.create("title" => "Title", "content" => "whatever") + assert !t.valid? + assert t.errors.on(:title) + assert_equal "will never be valid", t.errors["title"] + end + + def test_invalid_validator + Topic.validate 3 + assert_raise(ActiveRecord::ActiveRecordError) { t = Topic.create } + end + def test_throw_away_typing d = Developer.create "name" => "David", "salary" => "100,000" assert !d.valid? |