Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
A cheap knock off of the default validates_length_of validator, but checks the filesize of a Carrierwave attachment

Note that this validation runs both after the file is uploaded and after CarrierWave has processed the image. If your base uploader includes a filter to resize the image then the validation will be run against the resized image, not the original one that was uploaded. If this causes a problem for you, then you should avoid using a resizing filter on the base uploader and put any specific size requirements in a version instead.

So instead of this:

require 'carrierwave/processing/mini_magick'

class LogoUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  process :quality => 80
  process :resize_to_limit => [800, 800]
  process :convert => 'png'
  
  # ...
end

Do this:

require 'carrierwave/processing/mini_magick'

class LogoUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  process :convert => 'png'

  version :medium do
    process :quality => 80
    process :resize_to_limit => [800, 800]
  end

  # ...

end
# config/locales/en.yml
en:
errors:
messages:
wrong_size: "is the wrong size (should be %{file_size})"
size_too_small: "is too small (should be at least %{file_size})"
size_too_big: "is too big (should be at most %{file_size})"
# lib/file_size_validator.rb
# Based on: https://gist.github.com/795665
class FileSizeValidator < ActiveModel::EachValidator
MESSAGES = { :is => :wrong_size, :minimum => :size_too_small, :maximum => :size_too_big }.freeze
CHECKS = { :is => :==, :minimum => :>=, :maximum => :<= }.freeze
DEFAULT_TOKENIZER = lambda { |value| value.split(//) }
RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :tokenizer, :too_short, :too_long]
def initialize(options)
if range = (options.delete(:in) || options.delete(:within))
raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
options[:minimum], options[:maximum] = range.begin, range.end
options[:maximum] -= 1 if range.exclude_end?
end
super
end
def check_validity!
keys = CHECKS.keys & options.keys
if keys.empty?
raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
end
keys.each do |key|
value = options[key]
unless value.is_a?(Integer) && value >= 0
raise ArgumentError, ":#{key} must be a nonnegative Integer"
end
end
end
def validate_each(record, attribute, value)
raise(ArgumentError, "A CarrierWave::Uploader::Base object was expected") unless value.kind_of? CarrierWave::Uploader::Base
value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.kind_of?(String)
CHECKS.each do |key, validity_check|
next unless check_value = options[key]
value ||= [] if key == :maximum
value_size = value.size
next if value_size.send(validity_check, check_value)
errors_options = options.except(*RESERVED_OPTIONS)
errors_options[:file_size] = help.number_to_human_size check_value
default_message = options[MESSAGES[key]]
errors_options[:message] ||= default_message if default_message
record.errors.add(attribute, MESSAGES[key], errors_options)
end
end
def help
Helper.instance
end
class Helper
include Singleton
include ActionView::Helpers::NumberHelper
end
end
@michaelbarlow7

This comment has been minimized.

Show comment Hide comment
@michaelbarlow7

michaelbarlow7 Aug 31, 2011

In your en.yml you spelled "too" wrong twice.

In your en.yml you spelled "too" wrong twice.

@chrisbloom7

This comment has been minimized.

Show comment Hide comment
@chrisbloom7

chrisbloom7 Aug 31, 2011

Fixed, thanks!

Owner

chrisbloom7 commented Aug 31, 2011

Fixed, thanks!

@michaelbarlow7

This comment has been minimized.

Show comment Hide comment
@michaelbarlow7

michaelbarlow7 Aug 31, 2011

No worries, thank you for the validator :)

No worries, thank you for the validator :)

@jDeppen

This comment has been minimized.

Show comment Hide comment
@jDeppen

jDeppen Sep 29, 2011

Is this before or after upload? Does it wait until the 10GB file has uploaded to say it's too big?

jDeppen commented Sep 29, 2011

Is this before or after upload? Does it wait until the 10GB file has uploaded to say it's too big?

@chrisbloom7

This comment has been minimized.

Show comment Hide comment
@chrisbloom7

chrisbloom7 Sep 29, 2011

After upload. Carrierwave wouldn't be able to report the real file size until it was fully uploaded. AFAIK browsers don't send file size info and if they did it could easily be spoofed.

Owner

chrisbloom7 commented Sep 29, 2011

After upload. Carrierwave wouldn't be able to report the real file size until it was fully uploaded. AFAIK browsers don't send file size info and if they did it could easily be spoofed.

@jDeppen

This comment has been minimized.

Show comment Hide comment
@jDeppen

jDeppen Sep 29, 2011

Ok thank you, maybe I can have it timeout if it goes too long.

jDeppen commented Sep 29, 2011

Ok thank you, maybe I can have it timeout if it goes too long.

@chrisbloom7

This comment has been minimized.

Show comment Hide comment
@chrisbloom7

chrisbloom7 Sep 29, 2011

You may try asking about this on http://stackoverflow.com. I think it's a good question of whether there is a reliable way of doing this before uploading. One thing I can think of is maybe some kind of flash uploader component that would be able to read the file being selected, check the file size, maybe make a query to the server for any other requirements, and do some pre-validation on the client side before the form is submitted. Let me know how you make out, I'm interested in hearing if there is a solution.

Owner

chrisbloom7 commented Sep 29, 2011

You may try asking about this on http://stackoverflow.com. I think it's a good question of whether there is a reliable way of doing this before uploading. One thing I can think of is maybe some kind of flash uploader component that would be able to read the file being selected, check the file size, maybe make a query to the server for any other requirements, and do some pre-validation on the client side before the form is submitted. Let me know how you make out, I'm interested in hearing if there is a solution.

@chrisbloom7

This comment has been minimized.

Show comment Hide comment
@chrisbloom7

chrisbloom7 Sep 29, 2011

On the other hand, it's really only the user that is inconvenienced if they try to upload something that is 10GB when a smaller limit is clearly stated.

Owner

chrisbloom7 commented Sep 29, 2011

On the other hand, it's really only the user that is inconvenienced if they try to upload something that is 10GB when a smaller limit is clearly stated.

@jDeppen

This comment has been minimized.

Show comment Hide comment
@jDeppen

jDeppen Oct 4, 2011

Thanks for your help. I just worry about tying up resources.

jDeppen commented Oct 4, 2011

Thanks for your help. I just worry about tying up resources.

@emilford

This comment has been minimized.

Show comment Hide comment
@emilford

emilford Nov 11, 2011

Having trouble getting this to work. I've added the class to lib, restarted my rails server, and am still able to upload a 5MB file with validates :picture, file_size: { maximum: 4.megabytes }

Having trouble getting this to work. I've added the class to lib, restarted my rails server, and am still able to upload a 5MB file with validates :picture, file_size: { maximum: 4.megabytes }

@chrisbloom7

This comment has been minimized.

Show comment Hide comment
@chrisbloom7

chrisbloom7 Nov 15, 2011

@emilford - It should be defined like this:

validates :picture,
  :file_size => { 
    :maximum => 4.megabytes.to_i
  }
Owner

chrisbloom7 commented Nov 15, 2011

@emilford - It should be defined like this:

validates :picture,
  :file_size => { 
    :maximum => 4.megabytes.to_i
  }
@emilford

This comment has been minimized.

Show comment Hide comment
@emilford

emilford Nov 15, 2011

Both syntaxes work...what I had was just the new 1.9.x hash syntax. I just noticed that a resize_to_fill was dropping my 5MB file in size, so the validation was never hit. Thanks for this.

Both syntaxes work...what I had was just the new 1.9.x hash syntax. I just noticed that a resize_to_fill was dropping my 5MB file in size, so the validation was never hit. Thanks for this.

@hyperrjas

This comment has been minimized.

Show comment Hide comment
@hyperrjas

hyperrjas Dec 21, 2011

where can i find a validator for mongoid? Thank you

where can i find a validator for mongoid? Thank you

@jamesfend

This comment has been minimized.

Show comment Hide comment
@jamesfend

jamesfend Jan 16, 2012

Thanks man. Worked perfect

Thanks man. Worked perfect

@ruseel

This comment has been minimized.

Show comment Hide comment
@ruseel

ruseel Feb 3, 2012

@hyperrjas This validator works for me with mongoid.
@chrisbloom7 Thank you

ruseel commented Feb 3, 2012

@hyperrjas This validator works for me with mongoid.
@chrisbloom7 Thank you

@hyperrjas

This comment has been minimized.

Show comment Hide comment
@hyperrjas

hyperrjas Feb 3, 2012

@ruseel For me it does not works for mongoid: I have in model:

require 'file_size_validator'
class Post
  include Mongoid::Document
  mount_uploader :posted, PostedUploader, mount_on: :posted_filename
  field :posted
  field :posted_cache
  field :remove_posted
  field :remote_posted_url
  validates :posted, :presence => true, :file_size => { :maximum => 0.5.megabytes.to_i  } 
end

and I upload since my pc with 5 mb for example, and the image its uploaded with 5 mb size.

I have in my posted_uploader.rb

require 'carrierwave/processing/mini_magick'
class PostedUploader < CarrierWave::Uploader::Base
 include CarrierWave::MiniMagick
 storage :grid_fs

 def store_dir
  "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
 end

process :resize_to_limit => [560, 560]
process :convert => :png

#versions
      version :medium do
        process :resize_to_fit => [200,380]
        process :convert => :png
      end

      version :big do
        process :resize_to_limit => [560, 560]
        process :convert => :png
      end

     version :thumb do
        process :resize_to_fill => [61, 61]
        process :convert => :png
      end 

      version :superthumb do
        process :resize_to_fill => [50, 50]
        process :convert => :png
      end 

    def extension_white_list
     %w(jpg jpeg gif png)
    end

    def filename
       if not super.nil?
        super.chomp(File.extname(super)) + '.png'
      end
    end

end

Where is the problem? Why the validate does not works and I can upload image greather than 0.5 mb?

Thank you!

@ruseel For me it does not works for mongoid: I have in model:

require 'file_size_validator'
class Post
  include Mongoid::Document
  mount_uploader :posted, PostedUploader, mount_on: :posted_filename
  field :posted
  field :posted_cache
  field :remove_posted
  field :remote_posted_url
  validates :posted, :presence => true, :file_size => { :maximum => 0.5.megabytes.to_i  } 
end

and I upload since my pc with 5 mb for example, and the image its uploaded with 5 mb size.

I have in my posted_uploader.rb

require 'carrierwave/processing/mini_magick'
class PostedUploader < CarrierWave::Uploader::Base
 include CarrierWave::MiniMagick
 storage :grid_fs

 def store_dir
  "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
 end

process :resize_to_limit => [560, 560]
process :convert => :png

#versions
      version :medium do
        process :resize_to_fit => [200,380]
        process :convert => :png
      end

      version :big do
        process :resize_to_limit => [560, 560]
        process :convert => :png
      end

     version :thumb do
        process :resize_to_fill => [61, 61]
        process :convert => :png
      end 

      version :superthumb do
        process :resize_to_fill => [50, 50]
        process :convert => :png
      end 

    def extension_white_list
     %w(jpg jpeg gif png)
    end

    def filename
       if not super.nil?
        super.chomp(File.extname(super)) + '.png'
      end
    end

end

Where is the problem? Why the validate does not works and I can upload image greather than 0.5 mb?

Thank you!

@ghost

This comment has been minimized.

Show comment Hide comment
@ghost

ghost Feb 19, 2012

If you need to pass in a method name as the value try this: https://gist.github.com/1862084

ghost commented Feb 19, 2012

If you need to pass in a method name as the value try this: https://gist.github.com/1862084

@hyperrjas

This comment has been minimized.

Show comment Hide comment
@hyperrjas

hyperrjas Feb 19, 2012

@kolaboratory Thank you for this lib, but in my model, with this does not works:

 validates :posted, :file_size => { :maximum => 0.5.megabytes.to_i  } 

What have I that write in my model?

Thank you again!

@kolaboratory Thank you for this lib, but in my model, with this does not works:

 validates :posted, :file_size => { :maximum => 0.5.megabytes.to_i  } 

What have I that write in my model?

Thank you again!

@imehesz

This comment has been minimized.

Show comment Hide comment
@imehesz

imehesz Mar 2, 2012

Hello,

I have the same issue as @hyperrjas. Added the validator into the /lib folder and getting the following err:
Unknown validator: 'FileSizeValidator'

Using Rails 3.2.1 (i'm new to Rails so this might be something very simple)

My Model code looks like this:

validates :screenshot,
    :presence => true,
    :file_size => {
        :maximum => 5.megabytes.to_i
    }

actually, I just added the YML piece and now I'm getting this ...
"undefined method `key?' for nil:NilClass"

thanks for your help.

--i

imehesz commented Mar 2, 2012

Hello,

I have the same issue as @hyperrjas. Added the validator into the /lib folder and getting the following err:
Unknown validator: 'FileSizeValidator'

Using Rails 3.2.1 (i'm new to Rails so this might be something very simple)

My Model code looks like this:

validates :screenshot,
    :presence => true,
    :file_size => {
        :maximum => 5.megabytes.to_i
    }

actually, I just added the YML piece and now I'm getting this ...
"undefined method `key?' for nil:NilClass"

thanks for your help.

--i

@chrisbloom7

This comment has been minimized.

Show comment Hide comment
@chrisbloom7

chrisbloom7 Mar 2, 2012

@imehesz - did you remember to require the validator in the model file?

require 'file_size_validator'
class Whatever < ActiveRecord::Base

If that's not the solution then you will need to post the full stack trace of the error, including line numbers and file names.

Owner

chrisbloom7 commented Mar 2, 2012

@imehesz - did you remember to require the validator in the model file?

require 'file_size_validator'
class Whatever < ActiveRecord::Base

If that's not the solution then you will need to post the full stack trace of the error, including line numbers and file names.

@imehesz

This comment has been minimized.

Show comment Hide comment
@imehesz

imehesz Mar 2, 2012

@chrisbloom7,

that's what it was! I knew it was something silly.
works like a charm ...

thanks,
--iM

imehesz commented Mar 2, 2012

@chrisbloom7,

that's what it was! I knew it was something silly.
works like a charm ...

thanks,
--iM

@chrisbloom7

This comment has been minimized.

Show comment Hide comment
@chrisbloom7

chrisbloom7 Mar 5, 2012

@emilford - thanks for the tip about when the image is validated against. I've added a note to the gist to highlight this issue.

Owner

chrisbloom7 commented Mar 5, 2012

@emilford - thanks for the tip about when the image is validated against. I've added a note to the gist to highlight this issue.

@emilford

This comment has been minimized.

Show comment Hide comment
@emilford

emilford Mar 5, 2012

@chrisbloom7, sure thing.

emilford commented Mar 5, 2012

@chrisbloom7, sure thing.

@bokor

This comment has been minimized.

Show comment Hide comment
@bokor

bokor Apr 14, 2012

Even through the validation is working, the image is still getting cached for me. Is there anyway around this?

bokor commented Apr 14, 2012

Even through the validation is working, the image is still getting cached for me. Is there anyway around this?

@chrisbloom7

This comment has been minimized.

Show comment Hide comment
@chrisbloom7

chrisbloom7 Apr 16, 2012

I'm assuming you mean cached as in stored to the temp folder. No there is no way around that as CarrierWave has to store it somewhere first before the file can be available for validation. You could use an after_validation callback to cleanup the temp file if the validation fails, or have a worker process do that periodically on older temp files.

Owner

chrisbloom7 commented Apr 16, 2012

I'm assuming you mean cached as in stored to the temp folder. No there is no way around that as CarrierWave has to store it somewhere first before the file can be available for validation. You could use an after_validation callback to cleanup the temp file if the validation fails, or have a worker process do that periodically on older temp files.

@bokor

This comment has been minimized.

Show comment Hide comment
@bokor

bokor Apr 16, 2012

Chris,

Thanks for getting back to me. Do you know what methods to call to make this happen? I can't seem to figure out how to get those to clean up. I have tried various things and they haven't worked. I would like to encapsulate everything on the Mounted Uploader, but not sure if that would work either.

bokor commented Apr 16, 2012

Chris,

Thanks for getting back to me. Do you know what methods to call to make this happen? I can't seem to figure out how to get those to clean up. I have tried various things and they haven't worked. I would like to encapsulate everything on the Mounted Uploader, but not sure if that would work either.

@chrisbloom7

This comment has been minimized.

Show comment Hide comment
@chrisbloom7

chrisbloom7 Apr 16, 2012

Before the image is saved the full path to the temp image is stored in the attribute you've mounted the uploader on. So for instance:

 > i = Contest.new
 => #<Contest > 
 > i.image = File.open(Rails.root.join('spec', 'support', 'images', '0.5_mb.jpg'))
 => #<File:/Users/chrisbloom7/Projects/foo/spec/support/images/0.5_mb.jpg> 
 > i.image
 => /Users/chrisbloom7/Projects/foo/tmp/uploads/development/20120416-1201-4288-3087/0.5_mb.jpg 

So in your after_validation callback method, check to see if the instance's errors hash contains a key for your mounted attribute, and if so delete the image in the specified path.

Owner

chrisbloom7 commented Apr 16, 2012

Before the image is saved the full path to the temp image is stored in the attribute you've mounted the uploader on. So for instance:

 > i = Contest.new
 => #<Contest > 
 > i.image = File.open(Rails.root.join('spec', 'support', 'images', '0.5_mb.jpg'))
 => #<File:/Users/chrisbloom7/Projects/foo/spec/support/images/0.5_mb.jpg> 
 > i.image
 => /Users/chrisbloom7/Projects/foo/tmp/uploads/development/20120416-1201-4288-3087/0.5_mb.jpg 

So in your after_validation callback method, check to see if the instance's errors hash contains a key for your mounted attribute, and if so delete the image in the specified path.

@bokor

This comment has been minimized.

Show comment Hide comment
@bokor

bokor Apr 16, 2012

Perfect...thank you!

bokor commented Apr 16, 2012

Perfect...thank you!

@chrisbloom7

This comment has been minimized.

Show comment Hide comment
@chrisbloom7

chrisbloom7 Apr 16, 2012

You might also try posting to the CW Google Group to see if the Uploaders have a built in mechanism for handling this.

Owner

chrisbloom7 commented Apr 16, 2012

You might also try posting to the CW Google Group to see if the Uploaders have a built in mechanism for handling this.

@hyperrjas

This comment has been minimized.

Show comment Hide comment
@hyperrjas

hyperrjas May 8, 2012

Hi guys, I get this error for spanish language:

I18n::MissingTranslationData in ItemsController#create
translation missing: es.number.human.storage_units.format

lib/file_size_validator.rb:51:in `block in validate_each'
lib/file_size_validator.rb:42:in `each'
lib/file_size_validator.rb:42:in `validate_each'
app/controllers/items_controller.rb:76:in `block in create'
app/controllers/items_controller.rb:75:in `create'

How can I fix this error for differents languages?
Thank you

Hi guys, I get this error for spanish language:

I18n::MissingTranslationData in ItemsController#create
translation missing: es.number.human.storage_units.format

lib/file_size_validator.rb:51:in `block in validate_each'
lib/file_size_validator.rb:42:in `each'
lib/file_size_validator.rb:42:in `validate_each'
app/controllers/items_controller.rb:76:in `block in create'
app/controllers/items_controller.rb:75:in `create'

How can I fix this error for differents languages?
Thank you

@ruseel

This comment has been minimized.

Show comment Hide comment
@ruseel

ruseel May 9, 2012

@hyperrjas Try 'rails-i18n' gem in your Gemfile.

ruseel commented May 9, 2012

@hyperrjas Try 'rails-i18n' gem in your Gemfile.

@chrisbloom7

This comment has been minimized.

Show comment Hide comment
@chrisbloom7

chrisbloom7 May 9, 2012

Edit: Try @ruseel's suggestion first

@hyperrjas Copy the entries from the config/locales/en.yml file above into config/locales/es.yml and provide the proper translations.

Owner

chrisbloom7 commented May 9, 2012

Edit: Try @ruseel's suggestion first

@hyperrjas Copy the entries from the config/locales/en.yml file above into config/locales/es.yml and provide the proper translations.

@hyperrjas

This comment has been minimized.

Show comment Hide comment
@hyperrjas

hyperrjas May 9, 2012

Thank you the @ruseel's suggestion has solved the problem :D. Thank you very much!

Thank you the @ruseel's suggestion has solved the problem :D. Thank you very much!

@lidashuang

This comment has been minimized.

Show comment Hide comment
@lidashuang

lidashuang Oct 24, 2012

Thanks

Thanks

@shlima

This comment has been minimized.

Show comment Hide comment
@shlima

shlima Mar 15, 2013

Thank you!

shlima commented Mar 15, 2013

Thank you!

@marcusg

This comment has been minimized.

Show comment Hide comment
@marcusg

marcusg Apr 23, 2013

thanks!

marcusg commented Apr 23, 2013

thanks!

@danman01

This comment has been minimized.

Show comment Hide comment
@danman01

danman01 Jun 23, 2013

I'm getting an exception (unknown validator) when running rspec tests - is there a place I should include the file_size_validator somewhere in rspec? Thanks

I'm getting an exception (unknown validator) when running rspec tests - is there a place I should include the file_size_validator somewhere in rspec? Thanks

@bosskovic

This comment has been minimized.

Show comment Hide comment
@bosskovic

bosskovic Aug 13, 2013

I was getting "comparison of String with 0 failed" exception in the line 51 for the values larger then 1023, until I added precision:

errors_options[:file_size] = help.number_to_human_size check_value, :precision => 5

Now it works fine.

Ruby 2.0.0-p247
Rails 3.2.13

I was getting "comparison of String with 0 failed" exception in the line 51 for the values larger then 1023, until I added precision:

errors_options[:file_size] = help.number_to_human_size check_value, :precision => 5

Now it works fine.

Ruby 2.0.0-p247
Rails 3.2.13

@szymon-przybyl

This comment has been minimized.

Show comment Hide comment
@szymon-przybyl

szymon-przybyl Sep 5, 2013

why not merge it into CarrierWave? :)

why not merge it into CarrierWave? :)

@RKushnir

This comment has been minimized.

Show comment Hide comment
@RKushnir

RKushnir Sep 11, 2013

I'm debugging the code because it's giving me undefined method '<=' for nil:NilClass), that's on the line next if value_size.send(validity_check, check_value).
The options I'm passing: validates :profile_img, file_size: {maximum: 2.megabytes.to_i}.

The following 2 lines don't make sense for me:

raise(ArgumentError, "A CarrierWave::Uploader::Base object was expected") unless value.kind_of? CarrierWave::Uploader::Base
value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.kind_of?(String)

Maybe I'm missing something, but value cannot be of type Uploader and String at the same time:

>   CarrierWave::Uploader::Base.new.kind_of? String
=> false 
> "abc".kind_of? CarrierWave::Uploader::Base
=> false 

I'm debugging the code because it's giving me undefined method '<=' for nil:NilClass), that's on the line next if value_size.send(validity_check, check_value).
The options I'm passing: validates :profile_img, file_size: {maximum: 2.megabytes.to_i}.

The following 2 lines don't make sense for me:

raise(ArgumentError, "A CarrierWave::Uploader::Base object was expected") unless value.kind_of? CarrierWave::Uploader::Base
value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.kind_of?(String)

Maybe I'm missing something, but value cannot be of type Uploader and String at the same time:

>   CarrierWave::Uploader::Base.new.kind_of? String
=> false 
> "abc".kind_of? CarrierWave::Uploader::Base
=> false 
@RKushnir

This comment has been minimized.

Show comment Hide comment
@RKushnir

RKushnir Sep 11, 2013

I discovered this was caused by some coincidence: I was migrating from paperclip and some records already had uploads, so carrierwave was thinking they are valid. I'm hosting on Azure, so I used carrierwave-azure which makes an HTTP request to get the file size and returns nil, instead of 0, if the file is unavailable. The solution was to just clear the outdated values in the upload column. Maybe this helps someone in a similar situation.

Anyway, this validator is almost useless(besides making a human readable file size in the error message), as you can just use the standard Rails length validator.

I discovered this was caused by some coincidence: I was migrating from paperclip and some records already had uploads, so carrierwave was thinking they are valid. I'm hosting on Azure, so I used carrierwave-azure which makes an HTTP request to get the file size and returns nil, instead of 0, if the file is unavailable. The solution was to just clear the outdated values in the upload column. Maybe this helps someone in a similar situation.

Anyway, this validator is almost useless(besides making a human readable file size in the error message), as you can just use the standard Rails length validator.

@roberthimler

This comment has been minimized.

Show comment Hide comment
@roberthimler

roberthimler Oct 24, 2013

Works for me the only problem is if the file is too big it ends up saving the file in my application's /uploads/tmp/ directory. Any ideas of how to avoid this from happening and delete the file?

Works for me the only problem is if the file is too big it ends up saving the file in my application's /uploads/tmp/ directory. Any ideas of how to avoid this from happening and delete the file?

@saeedSarpas

This comment has been minimized.

Show comment Hide comment
@saeedSarpas

saeedSarpas May 1, 2014

What is the right way to set maximum file size amount for test env?
I did something like this:

file_size: { maximum: (Rails.env.test? ? 1.megabytes.to_i : 5.megabytes.to_i }

but I don't feel it's right.

What is the right way to set maximum file size amount for test env?
I did something like this:

file_size: { maximum: (Rails.env.test? ? 1.megabytes.to_i : 5.megabytes.to_i }

but I don't feel it's right.

@jmuheim

This comment has been minimized.

Show comment Hide comment
@jmuheim

jmuheim Jul 19, 2014

@saeedSarpas: I'm thinking about this, too. Is there a way to stub the validation within the test itself?

At least, I prettified your code a little:

validates :avatar, file_size: {maximum: (Rails.env.test? ? 5 : 100).kilobytes.to_i}

jmuheim commented Jul 19, 2014

@saeedSarpas: I'm thinking about this, too. Is there a way to stub the validation within the test itself?

At least, I prettified your code a little:

validates :avatar, file_size: {maximum: (Rails.env.test? ? 5 : 100).kilobytes.to_i}
@heartfulbird

This comment has been minimized.

Show comment Hide comment
@heartfulbird

heartfulbird Sep 9, 2014

Hi! I'm using carrierwave and file_size_validator
and I'm using sidekiq
and when I run "bundle exec sidekiq " in console
i see this errors
.../lib/file_size_validator.rb:5: warning: already initialized constant FileSizeValidator::MESSAGES
and the same about
FileSizeValidator::CHECKS
and ::DEFAULT_TOKENIZER
and ::RESERVED_OPTIONS

Hi! I'm using carrierwave and file_size_validator
and I'm using sidekiq
and when I run "bundle exec sidekiq " in console
i see this errors
.../lib/file_size_validator.rb:5: warning: already initialized constant FileSizeValidator::MESSAGES
and the same about
FileSizeValidator::CHECKS
and ::DEFAULT_TOKENIZER
and ::RESERVED_OPTIONS

@musaffa

This comment has been minimized.

Show comment Hide comment
@musaffa

musaffa Dec 11, 2014

file validators gem does file validations more elegantly. It also supports validations both before and after uploads.

musaffa commented Dec 11, 2014

file validators gem does file validations more elegantly. It also supports validations both before and after uploads.

@pioz

This comment has been minimized.

Show comment Hide comment
@pioz

pioz Apr 22, 2015

@vinayvinay

This comment has been minimized.

Show comment Hide comment
@vinayvinay

vinayvinay Oct 13, 2015

Can anyone help me resolve this error that comes up while using this validator? For some reason the value.size calls .content_length on a nil.

lib/file_size_validator.rb:47:in `block in validate_each'
NoMethodError (undefined method `content_length' for nil:NilClass):
lib/file_size_validator.rb:42:in `each'
lib/file_size_validator.rb:42:in `validate_each'

Can anyone help me resolve this error that comes up while using this validator? For some reason the value.size calls .content_length on a nil.

lib/file_size_validator.rb:47:in `block in validate_each'
NoMethodError (undefined method `content_length' for nil:NilClass):
lib/file_size_validator.rb:42:in `each'
lib/file_size_validator.rb:42:in `validate_each'
@ch3m1c

This comment has been minimized.

Show comment Hide comment
@ch3m1c

ch3m1c Nov 24, 2015

Anyone using this with multiple files upload from Carrierwave? :)

ch3m1c commented Nov 24, 2015

Anyone using this with multiple files upload from Carrierwave? :)

@osnysantos

This comment has been minimized.

Show comment Hide comment
@osnysantos

osnysantos Dec 17, 2015

Im getting the same error as @vinayvinay

It seems that the asset was removed out of app and file_size_validator try to validate an nonexistent file.

Im getting the same error as @vinayvinay

It seems that the asset was removed out of app and file_size_validator try to validate an nonexistent file.

@mariorcardoso

This comment has been minimized.

Show comment Hide comment
@mariorcardoso

mariorcardoso Apr 4, 2017

@osnysantos I was experiencing the same error because the asset was not present (the url was broken). I added the the line next if value.present? && !(value.file.exists?) inside the validate_each loop so I don't get an exception when the file url is broken. It seems to work fine so far. If the url is broken I don't need to validate the file size.

checks.each do |key, validity_check|
      next unless check_value = options[key]

      value ||= [] if key == :maximum
      next if value.present? && !(value.file.exists?)

      value_size = value.size
      next if value_size.send(validity_check, check_value)

@osnysantos I was experiencing the same error because the asset was not present (the url was broken). I added the the line next if value.present? && !(value.file.exists?) inside the validate_each loop so I don't get an exception when the file url is broken. It seems to work fine so far. If the url is broken I don't need to validate the file size.

checks.each do |key, validity_check|
      next unless check_value = options[key]

      value ||= [] if key == :maximum
      next if value.present? && !(value.file.exists?)

      value_size = value.size
      next if value_size.send(validity_check, check_value)
@pinty

This comment has been minimized.

Show comment Hide comment
@pinty

pinty Jun 27, 2017

Hello @chrisbloom7
As we would like to use your source code present on this page, is there any chance that we can get a license for the code written by you into the following file file_size_validator.rb ? We couldn't find any.
Thank you!

pinty commented Jun 27, 2017

Hello @chrisbloom7
As we would like to use your source code present on this page, is there any chance that we can get a license for the code written by you into the following file file_size_validator.rb ? We couldn't find any.
Thank you!

@alexanderadam

This comment has been minimized.

Show comment Hide comment
@alexanderadam

alexanderadam Aug 5, 2017

Hey @pinty,

it's possible to replace it with file_validators gem mentioned above by it's author which has the MIT license.
Besides from that it's properly packaged, has specs and a dedicated issue tracker.

PS: I'm pretty sure I'm reading a document you (co-)authored 😉

alexanderadam commented Aug 5, 2017

Hey @pinty,

it's possible to replace it with file_validators gem mentioned above by it's author which has the MIT license.
Besides from that it's properly packaged, has specs and a dedicated issue tracker.

PS: I'm pretty sure I'm reading a document you (co-)authored 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment