Module: FileColumn::Validations::ClassMethods

Defined in:
lib/validations.rb

Overview

This module contains methods to create validations of uploaded files. All methods in this module will be included as class methods into ActiveRecord::Base so that you can use them in your models like this:

class Entry < ActiveRecord::Base
  file_column :image
  validates_filesize_of :image, :in => 0..1.megabyte
end

Constant Summary collapse

EXT_REGEXP =
/\.([A-z0-9]+)$/
IMAGE_SIZE_REGEXP =
/^(\d+)x(\d+)$/

Instance Method Summary collapse

Instance Method Details

#validates_file_format_of(*attrs) ⇒ Object

This validates the file type of one or more file_columns. A list of file columns should be given followed by an options hash.

Required options:

  • :in => list of extensions or mime types. If mime types are used they will be mapped into an extension via FileColumn::ClassMethods::MIME_EXTENSIONS.

Examples:

validates_file_format_of :field, :in => ["gif", "png", "jpg"]
validates_file_format_of :field, :in => ["image/jpeg"]

Raises:

  • (ArgumentError)

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/validations.rb', line 30

def validates_file_format_of(*attrs)

  options = attrs.pop if attrs.last.is_a?Hash
  raise ArgumentError, "Please include the :in option." if !options || !options[:in]
  options[:in] = [options[:in]] if options[:in].is_a?String
  raise ArgumentError, "Invalid value for option :in" unless options[:in].is_a?Array

  validates_each(attrs, options) do |record, attr, value|
    unless value.blank?
      mime_extensions = record.send("#{attr}_options")[:mime_extensions]
      extensions = options[:in].map{|o| mime_extensions[o] || o }
      record.errors.add attr, "is not a valid format." unless extensions.include?(value.scan(EXT_REGEXP).flatten.first)
    end
  end

end

#validates_filesize_of(*attrs) ⇒ Object

This validates the file size of one or more file_columns. A list of file columns should be given followed by an options hash.

Required options:

  • :in => A size range. Note that you can use ActiveSupport's numeric extensions for kilobytes, etc.

Examples:

validates_filesize_of :field, :in => 0..100.megabytes
validates_filesize_of :field, :in => 15.kilobytes..1.megabyte

Raises:

  • (ArgumentError)

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/validations.rb', line 57

def validates_filesize_of(*attrs)  

  options = attrs.pop if attrs.last.is_a?Hash
  raise ArgumentError, "Please include the :in option." if !options || !options[:in]
  raise ArgumentError, "Invalid value for option :in" unless options[:in].is_a?Range

  validates_each(attrs, options) do |record, attr, value|
    unless value.blank?
      size = File.size(value)
      record.errors.add attr, "is smaller than the allowed size range." if size < options[:in].first
      record.errors.add attr, "is larger than the allowed size range." if size > options[:in].last
    end
  end

end

#validates_image_size(*attrs) ⇒ Object

Validates the image size of one or more file_columns. A list of file columns should be given followed by an options hash. The validation will pass if both image dimensions (rows and columns) are at least as big as given in the :min option.

Required options:

  • :min => minimum image dimension string, in the format NNxNN (columns x rows).

Example:

validates_image_size :field, :min => "1200x1800"

This validation requires RMagick to be installed on your system to check the image's size.

Raises:

  • (ArgumentError)

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/validations.rb', line 89

def validates_image_size(*attrs)      
  options = attrs.pop if attrs.last.is_a?Hash
  raise ArgumentError, "Please include a :min option." if !options || !options[:min]
  minimums = options[:min].scan(IMAGE_SIZE_REGEXP).first.collect{|n| n.to_i} rescue []
  raise ArgumentError, "Invalid value for option :min (should be 'XXxYY')" unless minimums.size == 2

  require 'RMagick'

  validates_each(attrs, options) do |record, attr, value|
    unless value.blank?
      begin
        img = ::Magick::Image::read(value).first
        record.errors.add('image', "is too small, must be at least #{minimums[0]}x#{minimums[1]}") if ( img.rows < minimums[1] || img.columns < minimums[0] )
      rescue ::Magick::ImageMagickError
        record.errors.add('image', "invalid image")
      end
      img = nil
      GC.start
    end
  end
end