Skip to content
This repository
Browse code

Add AttachmentPresenceValidator

  • Loading branch information...
commit ee42b198a45e44c6174870a6854adfb6d51f699e 1 parent e83f88f
Prem Sichanugrist authored March 16, 2012
17  lib/paperclip.rb
@@ -195,23 +195,6 @@ def has_attached_file(name, options = {})
195 195
       end
196 196
     end
197 197
 
198  
-    # Places ActiveRecord-style validations on the presence of a file.
199  
-    # Options:
200  
-    # * +if+: A lambda or name of an instance method. Validation will only
201  
-    #   be run if this lambda or method returns true.
202  
-    # * +unless+: Same as +if+ but validates if lambda or method returns false.
203  
-    def validates_attachment_presence name, options = {}
204  
-      message = options[:message] || :empty
205  
-      validates_each :"#{name}_file_name" do |record, attr, value|
206  
-        if_clause_passed = options[:if].nil? || (options[:if].respond_to?(:call) ? options[:if].call(record) != false : record.send(options[:if]))
207  
-        unless_clause_passed = options[:unless].nil? || (options[:unless].respond_to?(:call) ? !!options[:unless].call(record) == false : !record.send(options[:unless]))
208  
-        if if_clause_passed && unless_clause_passed && value.blank?
209  
-          record.errors.add(name, message)
210  
-          record.errors.add("#{name}_file_name", message)
211  
-        end
212  
-      end
213  
-    end
214  
-
215 198
     # Places ActiveRecord-style validations on the content type of the file
216 199
     # assigned. The possible options are:
217 200
     # * +content_type+: Allowed content types.  Can be a single content type
1  lib/paperclip/validators.rb
... ...
@@ -1,4 +1,5 @@
1 1
 require 'active_support/concern'
  2
+require 'paperclip/validators/attachment_presence_validator'
2 3
 require 'paperclip/validators/attachment_size_validator'
3 4
 
4 5
 module Paperclip
26  lib/paperclip/validators/attachment_presence_validator.rb
... ...
@@ -0,0 +1,26 @@
  1
+require 'active_model/validations/presence'
  2
+
  3
+module Paperclip
  4
+  module Validators
  5
+    class AttachmentPresenceValidator < ActiveModel::Validations::PresenceValidator
  6
+      def validate(record)
  7
+        [attributes].flatten.map do |attribute|
  8
+          if record.send(:read_attribute_for_validation, "#{attribute}_file_name").blank?
  9
+            record.errors.add(attribute, :blank, options)
  10
+          end
  11
+        end
  12
+      end
  13
+    end
  14
+
  15
+    module HelperMethods
  16
+      # Places ActiveRecord-style validations on the presence of a file.
  17
+      # Options:
  18
+      # * +if+: A lambda or name of an instance method. Validation will only
  19
+      #   be run if this lambda or method returns true.
  20
+      # * +unless+: Same as +if+ but validates if lambda or method returns false.
  21
+      def validates_attachment_presence(*attr_names)
  22
+        validates_with AttachmentPresenceValidator, _merge_attributes(attr_names)
  23
+      end
  24
+    end
  25
+  end
  26
+end
85  test/validators/attachment_presence_validator_test.rb
... ...
@@ -0,0 +1,85 @@
  1
+require './test/helper'
  2
+
  3
+class AttachmentPresenceValidatorTest < Test::Unit::TestCase
  4
+  def setup
  5
+    rebuild_model
  6
+    @dummy = Dummy.new
  7
+  end
  8
+
  9
+  def build_validator(options={})
  10
+    @validator = Paperclip::Validators::AttachmentPresenceValidator.new(options.merge(
  11
+      :attributes => :avatar
  12
+    ))
  13
+  end
  14
+
  15
+  context "nil attachment" do
  16
+    setup do
  17
+      @dummy.avatar = nil
  18
+    end
  19
+
  20
+    context "with default options" do
  21
+      setup do
  22
+        build_validator
  23
+        @validator.validate(@dummy)
  24
+      end
  25
+
  26
+      should "add error on the attachment" do
  27
+        assert @dummy.errors[:avatar].present?
  28
+      end
  29
+
  30
+      should "not add an error on the file_name attribute" do
  31
+        assert @dummy.errors[:avatar_file_name].blank?
  32
+      end
  33
+    end
  34
+
  35
+    context "with :if option" do
  36
+      context "returning true" do
  37
+        setup do
  38
+          build_validator :if => true
  39
+          @validator.validate(@dummy)
  40
+        end
  41
+
  42
+        should "perform a validation" do
  43
+          assert @dummy.errors[:avatar].present?
  44
+        end
  45
+      end
  46
+
  47
+      context "returning false" do
  48
+        setup do
  49
+          build_validator :if => false
  50
+          @validator.validate(@dummy)
  51
+        end
  52
+
  53
+        should "perform a validation" do
  54
+          assert @dummy.errors[:avatar].present?
  55
+        end
  56
+      end
  57
+    end
  58
+  end
  59
+
  60
+  context "with attachment" do
  61
+    setup do
  62
+      build_validator
  63
+      @dummy.avatar = StringIO.new('.')
  64
+      @validator.validate(@dummy)
  65
+    end
  66
+
  67
+    should "not add error on the attachment" do
  68
+      assert @dummy.errors[:avatar].blank?
  69
+    end
  70
+
  71
+    should "not add an error on the file_name attribute" do
  72
+      assert @dummy.errors[:avatar_file_name].blank?
  73
+    end
  74
+  end
  75
+
  76
+  context "using the helper" do
  77
+    setup do
  78
+      Dummy.validates_attachment_presence :avatar
  79
+    end
  80
+
  81
+    should "add the validator to the class" do
  82
+      assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_presence }
  83
+    end
  84
+  end
  85
+end

0 notes on commit ee42b19

Please sign in to comment.
Something went wrong with that request. Please try again.