From 2583a27df497e72ec7a200b6aa707948e88fd166 Mon Sep 17 00:00:00 2001 From: Prem Sichanugrist Date: Fri, 21 Oct 2011 15:34:47 -0400 Subject: [PATCH] Fix a bug when passing a method name to `:if` and `:unless` option in `validates_attachment_presence` Fixes #631 --- lib/paperclip.rb | 6 +-- test/paperclip_test.rb | 84 +++++++++++++++++++++++++++++++----------- 2 files changed, 65 insertions(+), 25 deletions(-) diff --git a/lib/paperclip.rb b/lib/paperclip.rb index e64319e6e..007bc0670 100644 --- a/lib/paperclip.rb +++ b/lib/paperclip.rb @@ -385,13 +385,13 @@ def validates_attachment_thumbnails name, options = {} # Places ActiveRecord-style validations on the presence of a file. # Options: # * +if+: A lambda or name of a method on the instance. Validation will only - # be run is this lambda or method returns true. + # be run if this lambda or method returns true. # * +unless+: Same as +if+ but validates if lambda or method returns false. def validates_attachment_presence name, options = {} message = options[:message] || :empty validates_each :"#{name}_file_name" do |record, attr, value| - if_clause_passed = options[:if].nil? || (options[:if].call(record) != false) - unless_clause_passed = options[:unless].nil? || (!!options[:unless].call(record) == false) + if_clause_passed = options[:if].nil? || (options[:if].respond_to?(:call) ? options[:if].call(record) != false : record.send(options[:if])) + unless_clause_passed = options[:unless].nil? || (options[:unless].respond_to?(:call) ? !!options[:unless].call(record) == false : !record.send(options[:unless])) if if_clause_passed && unless_clause_passed && value.blank? record.errors.add(name, message) record.errors.add("#{name}_file_name", message) diff --git a/test/paperclip_test.rb b/test/paperclip_test.rb index d4412a7a3..1880b0ebb 100644 --- a/test/paperclip_test.rb +++ b/test/paperclip_test.rb @@ -170,38 +170,78 @@ class ::SubDummy < Dummy; end end context "a validation with an if guard clause" do - setup do - Dummy.send(:"validates_attachment_presence", :avatar, :if => lambda{|i| i.foo }) - @dummy = Dummy.new - @dummy.stubs(:avatar_file_name).returns(nil) - end + context "as a lambda" do + setup do + Dummy.send(:"validates_attachment_presence", :avatar, :if => lambda{|i| i.foo }) + @dummy = Dummy.new + @dummy.stubs(:avatar_file_name).returns(nil) + end + + should "attempt validation if the guard returns true" do + @dummy.expects(:foo).returns(true) + assert ! @dummy.valid? + end - should "attempt validation if the guard returns true" do - @dummy.expects(:foo).returns(true) - assert ! @dummy.valid? + should "not attempt validation if the guard returns false" do + @dummy.expects(:foo).returns(false) + assert @dummy.valid? + end end - should "not attempt validation if the guard returns false" do - @dummy.expects(:foo).returns(false) - assert @dummy.valid? + context "as a method name" do + setup do + Dummy.send(:"validates_attachment_presence", :avatar, :if => :foo) + @dummy = Dummy.new + @dummy.stubs(:avatar_file_name).returns(nil) + end + + should "attempt validation if the guard returns true" do + @dummy.expects(:foo).returns(true) + assert ! @dummy.valid? + end + + should "not attempt validation if the guard returns false" do + @dummy.expects(:foo).returns(false) + assert @dummy.valid? + end end end context "a validation with an unless guard clause" do - setup do - Dummy.send(:"validates_attachment_presence", :avatar, :unless => lambda{|i| i.foo }) - @dummy = Dummy.new - @dummy.stubs(:avatar_file_name).returns(nil) - end + context "as a lambda" do + setup do + Dummy.send(:"validates_attachment_presence", :avatar, :unless => lambda{|i| i.foo }) + @dummy = Dummy.new + @dummy.stubs(:avatar_file_name).returns(nil) + end + + should "attempt validation if the guard returns true" do + @dummy.expects(:foo).returns(false) + assert ! @dummy.valid? + end - should "attempt validation if the guard returns true" do - @dummy.expects(:foo).returns(false) - assert ! @dummy.valid? + should "not attempt validation if the guard returns false" do + @dummy.expects(:foo).returns(true) + assert @dummy.valid? + end end - should "not attempt validation if the guard returns false" do - @dummy.expects(:foo).returns(true) - assert @dummy.valid? + context "as a method name" do + setup do + Dummy.send(:"validates_attachment_presence", :avatar, :unless => :foo) + @dummy = Dummy.new + @dummy.stubs(:avatar_file_name).returns(nil) + end + + should "attempt validation if the guard returns true" do + @dummy.expects(:foo).returns(false) + assert ! @dummy.valid? + end + + should "not attempt validation if the guard returns false" do + @dummy.expects(:foo).returns(true) + assert @dummy.valid? + end end end