Commit 2aeb491f by Dan Collis-Puro Committed by Jon Yurek

Add content_type and size errors to base attribute

This propagates attachment size and content_type validations to the main
attachment attribute, to make them behave the same as presence
validations. This allows paperclip to play more nicely with simple_form
and other form abstraction gems.

This commit includes a behaviorial change. If you emit all errors on a
model instance you will see some failed validations twice: once for the
base attachment attribute and again for the failed presence,
content_type or size attachment attributes.
parent edea587f
......@@ -7,29 +7,31 @@ module Paperclip
end
def validate_each(record, attribute, value)
base_attribute = attribute.to_sym
attribute = "#{attribute}_content_type".to_sym
value = record.send :read_attribute_for_validation, attribute
return if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
validate_whitelist(record, attribute, value)
validate_blacklist(record, attribute, value)
validate_whitelist(record, base_attribute, attribute, value)
validate_blacklist(record, base_attribute, attribute, value)
end
def validate_whitelist(record, attribute, value)
def validate_whitelist(record, base_attribute, attribute, value)
if allowed_types.present? && allowed_types.none? { |type| type === value }
mark_invalid record, attribute, allowed_types
mark_invalid record, base_attribute, attribute, allowed_types
end
end
def validate_blacklist(record, attribute, value)
def validate_blacklist(record, base_attribute, attribute, value)
if forbidden_types.present? && forbidden_types.any? { |type| type === value }
mark_invalid record, attribute, forbidden_types
mark_invalid record, base_attribute, attribute, forbidden_types
end
end
def mark_invalid(record, attribute, types)
def mark_invalid(record, base_attribute, attribute, types)
record.errors.add attribute, :invalid, options.merge(:types => types.join(', '))
record.errors.add base_attribute, :invalid, options.merge(:types => types.join(', '))
end
def allowed_types
......
......@@ -11,6 +11,7 @@ module Paperclip
end
def validate_each(record, attr_name, value)
base_attr_name = attr_name
attr_name = "#{attr_name}_file_size".to_sym
value = record.send(:read_attribute_for_validation, attr_name)
......@@ -21,11 +22,13 @@ module Paperclip
unless value.send(CHECKS[option], option_value)
error_message_key = options[:in] ? :in_between : option
record.errors.add(attr_name, error_message_key, filtered_options(value).merge(
:min => min_value_in_human_size(record),
:max => max_value_in_human_size(record),
:count => human_size(option_value)
))
[ attr_name, base_attr_name ].each do |error_attr_name|
record.errors.add(error_attr_name, error_message_key, filtered_options(value).merge(
:min => min_value_in_human_size(record),
:max => max_value_in_human_size(record),
:count => human_size(option_value)
))
end
end
end
end
......
......@@ -50,6 +50,32 @@ class AttachmentContentTypeValidatorTest < Test::Unit::TestCase
end
end
context "with a failing validation" do
setup do
build_validator :content_type => "image/png", :allow_nil => false
@dummy.stubs(:avatar_content_type => nil)
@validator.validate(@dummy)
end
should "add error to the base object" do
assert @dummy.errors[:avatar].present?,
"Error not added to base attribute"
end
end
context "with a successful validation" do
setup do
build_validator :content_type => "image/png", :allow_nil => false
@dummy.stubs(:avatar_content_type => "image/png")
@validator.validate(@dummy)
end
should "not add error to the base object" do
assert @dummy.errors[:avatar].blank?,
"Error was added to base attribute"
end
end
context "with :allow_blank option" do
context "as true" do
setup do
......
......@@ -20,6 +20,11 @@ class AttachmentSizeValidatorTest < Test::Unit::TestCase
assert @dummy.errors[:avatar_file_size].blank?,
"Expect an error message on :avatar_file_size, got none."
end
should "not add error to the base dummy object" do
assert @dummy.errors[:avatar].blank?,
"Error added to base attribute"
end
end
end
......@@ -35,6 +40,11 @@ class AttachmentSizeValidatorTest < Test::Unit::TestCase
"Unexpected error message on :avatar_file_size"
end
should "add error to the base dummy object" do
assert @dummy.errors[:avatar].present?,
"Error not added to base attribute"
end
if options[:message]
should "return a correct error message" do
assert_includes @dummy.errors[:avatar_file_size], options[:message]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment