Reputation: 10207
I am using the following method to validate the file size of my images:
class ImageUploader < CarrierWave::Uploader::Base
def size_range
0..200.kilobytes
end
Unfortunately, the error message that my users are getting is a bit cryptic:
Image size should be less than 204800
Is there a way to change that to something more meaningful such as:
Image size should be less than 2 MB
I've tried various approaches but to no avail.
These are my localization files by the way:
errors:
messages:
min_size_error: size should be greater than %{min_size}
max_size_error: size should be less than %{max_size}
Thanks for any help.
Upvotes: 1
Views: 1749
Reputation: 12320
You can change the validation message by custom validator
like below
class Product < ActiveRecord::Base
mount_uploader :file, ImageUploader
validate :up_file_size
validate :down_file_size
def up_file_size
if file.file.size.to_f/(1000*1000) > 200.kilobytes
errors.add(:file, "size should be less than #{max_upload_limit.to_f}MB")
end
end
def down_file_size
if file.file.size.to_f/(1000*1000) < 0
errors.add(:file, "size should be greater than #{min_upload_limit.to_f}MB")
end
end
end
Upvotes: 1
Reputation: 5204
To make an error message more friendly override carrierwave's check_size! method in your FileUploader with below code:
class ImageUploader < CarrierWave::Uploader::Base
def size_range
0..200.kilobytes
end
private
def check_size!(new_file)
size = new_file.size
expected_size_range = size_range
if expected_size_range.is_a?(::Range)
if size < expected_size_range.min
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.min_size_error", :min_size => ApplicationController.helpers.number_to_human_size(expected_size_range.min))
elsif size > expected_size_range.max
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.max_size_error", :max_size => ApplicationController.helpers.number_to_human_size(expected_size_range.max))
end
end
end
end
Upvotes: 4
Reputation: 28305
By using the built-in file size validator, you are unfortunately tied down to its implementation:
def check_size!(new_file)
size = new_file.size
expected_size_range = size_range
if expected_size_range.is_a?(::Range)
if size < expected_size_range.min
raise CarrierWave::IntegrityError,
I18n.translate(
:"errors.messages.min_size_error",
:min_size => expected_size_range.min
)
elsif size > expected_size_range.max
raise CarrierWave::IntegrityError,
I18n.translate(
:"errors.messages.max_size_error",
:max_size => expected_size_range.max
)
end
end
end
You could simply override that method to provide some other value for min_size
and max_size
(e.g. the number of Megabytes rather than Bytes).
Or alternatively, as explained the CarrierWave wiki, you could use a gem like file_validators, or copy this gist, or even quite easily write your own file validator rather than relying on the built-in CarrierWave version.
The simplest custom validator example given on that page (which I'm only copy+pasting here in case the link dies in the future) is:
# app/models/user.rb
class User< ActiveRecord::Base
attr_accessible :product_upload_limit
has_many :products
end
# app/models/brand.rb
class Product < ActiveRecord::Base
mount_uploader :file, FileUploader
belongs_to :user
validate :file_size
def file_size
if file.file.size.to_f/(1000*1000) > user.product_upload_limit.to_f
errors.add(:file, "You cannot upload a file greater than #{upload_limit.to_f}MB")
end
end
end
Upvotes: 1