Use file_validators to validate attachments

We were using custom rules because of some issues with Paperclip. These
rules work fine, but since we're already using the file_validators gem,
we might as well simplify the code a little bit.
This commit is contained in:
Javi Martín
2021-07-28 02:51:49 +02:00
parent 7212657c02
commit 5ff66f96cd
3 changed files with 22 additions and 21 deletions

View File

@@ -7,8 +7,26 @@ module Attachable
attr_accessor :cached_attachment attr_accessor :cached_attachment
validate :attachment_presence validate :attachment_presence
validate :validate_attachment_content_type, if: -> { attachment.attached? }
validate :validate_attachment_size, if: -> { attachment.attached? } validates :attachment,
file_content_type: {
allow: ->(record) { record.accepted_content_types },
if: -> { association_class && attachment.attached? },
message: ->(record, *) do
I18n.t("#{record.model_name.plural}.errors.messages.wrong_content_type",
content_type: record.attachment_content_type,
accepted_content_types: record.class.humanized_accepted_content_types)
end
},
file_size: {
less_than_or_equal_to: ->(record) { record.max_file_size.megabytes },
if: -> { association_class && attachment.attached? },
message: ->(record, *) do
I18n.t("#{record.model_name.plural}.errors.messages.in_between",
min: "0 Bytes",
max: "#{record.max_file_size} MB")
end
}
before_validation :set_attachment_from_cached_attachment, if: -> { cached_attachment.present? } before_validation :set_attachment_from_cached_attachment, if: -> { cached_attachment.present? }
end end
@@ -49,23 +67,6 @@ module Attachable
private private
def validate_attachment_size
if association_class && attachment_file_size > max_file_size.megabytes
errors.add(:attachment, I18n.t("#{model_name.plural}.errors.messages.in_between",
min: "0 Bytes",
max: "#{max_file_size} MB"))
end
end
def validate_attachment_content_type
if association_class && !accepted_content_types.include?(attachment_content_type)
message = I18n.t("#{model_name.plural}.errors.messages.wrong_content_type",
content_type: attachment_content_type,
accepted_content_types: self.class.humanized_accepted_content_types)
errors.add(:attachment, message)
end
end
def attachment_presence def attachment_presence
unless attachment.attached? unless attachment.attached?
errors.add(:attachment, I18n.t("errors.messages.blank")) errors.add(:attachment, I18n.t("errors.messages.blank"))

View File

@@ -29,7 +29,7 @@ shared_examples "document validations" do |documentable_factory|
end end
it "is not valid for attachments larger than documentable max_file_size definition" do it "is not valid for attachments larger than documentable max_file_size definition" do
allow(document).to receive(:attachment_file_size).and_return(maxfilesize.megabytes + 1.byte) allow(document.attachment).to receive(:byte_size).and_return(maxfilesize.megabytes + 1.byte)
max_size_error_message = "must be in between 0 Bytes and #{maxfilesize} MB" max_size_error_message = "must be in between 0 Bytes and #{maxfilesize} MB"
expect(document).not_to be_valid expect(document).not_to be_valid

View File

@@ -38,7 +38,7 @@ shared_examples "image validations" do |imageable_factory|
it "is not valid for attachments larger than imageable max_file_size definition" do it "is not valid for attachments larger than imageable max_file_size definition" do
larger_size = Setting["uploads.images.max_size"].to_i.megabytes + 1.byte larger_size = Setting["uploads.images.max_size"].to_i.megabytes + 1.byte
allow(image).to receive(:attachment_file_size).and_return(larger_size) allow(image.attachment).to receive(:byte_size).and_return(larger_size)
expect(image).not_to be_valid expect(image).not_to be_valid
expect(image.errors[:attachment]).to include "must be in between 0 Bytes and 1 MB" expect(image.errors[:attachment]).to include "must be in between 0 Bytes and 1 MB"