Move attachable methods from helpers to models

We were using helper methods inside the model; we might as well include
them in the model and use them from anywhere else.

Note we're using a different logic for images and documents methods.
That's because for images the logic was defined in the helper methods,
but for documents the logic is defined in the Documentable concern. In
the past, different documentable classes allowed different content
types, while imageable classes have always allowed the same content
types.

I'm not sure which method is better; for now, I'm leaving it the way it
was (except for the fact that we're removing the helper methods).
This commit is contained in:
Javi Martín
2021-07-24 02:20:59 +02:00
parent 4d8842c0d4
commit b52ceb2c78
8 changed files with 46 additions and 47 deletions

View File

@@ -1,6 +1,5 @@
class Documents::NestedComponent < ApplicationComponent class Documents::NestedComponent < ApplicationComponent
attr_reader :f attr_reader :f
delegate :documentable_humanized_accepted_content_types, to: :helpers
def initialize(f) def initialize(f)
@f = f @f = f
@@ -18,7 +17,7 @@ class Documents::NestedComponent < ApplicationComponent
def note def note
t "documents.form.note", max_documents_allowed: max_documents_allowed, t "documents.form.note", max_documents_allowed: max_documents_allowed,
accepted_content_types: documentable_humanized_accepted_content_types(documentable.class), accepted_content_types: Document.humanized_accepted_content_types,
max_file_size: documentable.class.max_file_size max_file_size: documentable.class.max_file_size
end end

View File

@@ -1,6 +1,5 @@
class Images::NestedComponent < ApplicationComponent class Images::NestedComponent < ApplicationComponent
attr_reader :f, :image_fields attr_reader :f, :image_fields
delegate :imageable_humanized_accepted_content_types, :imageable_max_file_size, to: :helpers
def initialize(f, image_fields: :image) def initialize(f, image_fields: :image)
@f = f @f = f
@@ -14,7 +13,7 @@ class Images::NestedComponent < ApplicationComponent
end end
def note def note
t "images.form.note", accepted_content_types: imageable_humanized_accepted_content_types, t "images.form.note", accepted_content_types: Image.humanized_accepted_content_types,
max_file_size: imageable_max_file_size max_file_size: Image.max_file_size
end end
end end

View File

@@ -1,9 +0,0 @@
module DocumentablesHelper
def accepted_content_types(documentable_class)
documentable_class.accepted_content_types
end
def documentable_humanized_accepted_content_types(documentable_class)
Setting.accepted_content_types_for("documents").join(", ")
end
end

View File

@@ -2,16 +2,4 @@ module ImageablesHelper
def can_destroy_image?(imageable) def can_destroy_image?(imageable)
imageable.image.present? && can?(:destroy, imageable.image) imageable.image.present? && can?(:destroy, imageable.image)
end end
def imageable_max_file_size
Setting["uploads.images.max_size"].to_i
end
def imageable_accepted_content_types
Setting["uploads.images.content_types"]&.split(" ") || ["image/jpeg"]
end
def imageable_humanized_accepted_content_types
Setting.accepted_content_types_for("images").join(", ")
end
end end

View File

@@ -1,5 +1,4 @@
class Document < ApplicationRecord class Document < ApplicationRecord
include DocumentablesHelper
has_attached_file :attachment, url: "/system/:class/:prefix/:style/:hash.:extension", has_attached_file :attachment, url: "/system/:class/:prefix/:style/:hash.:extension",
hash_data: ":class/:style/:custom_hash_data", hash_data: ":class/:style/:custom_hash_data",
use_timestamp: false, use_timestamp: false,
@@ -48,6 +47,10 @@ class Document < ApplicationRecord
attachment.instance.custom_hash_data(attachment) attachment.instance.custom_hash_data(attachment)
end end
def self.humanized_accepted_content_types
Setting.accepted_content_types_for("documents").join(", ")
end
def prefix(attachment, _style) def prefix(attachment, _style)
if attachment.instance.persisted? if attachment.instance.persisted?
":attachment/:id_partition" ":attachment/:id_partition"
@@ -69,6 +72,14 @@ class Document < ApplicationRecord
attachment_content_type.split("/").last.upcase attachment_content_type.split("/").last.upcase
end end
def max_file_size
documentable_class.max_file_size
end
def accepted_content_types
documentable_class.accepted_content_types
end
private private
def documentable_class def documentable_class
@@ -77,20 +88,18 @@ class Document < ApplicationRecord
def validate_attachment_size def validate_attachment_size
if documentable_class.present? && if documentable_class.present? &&
attachment_file_size > documentable_class.max_file_size.megabytes attachment_file_size > max_file_size.megabytes
errors.add(:attachment, I18n.t("documents.errors.messages.in_between", errors.add(:attachment, I18n.t("documents.errors.messages.in_between",
min: "0 Bytes", min: "0 Bytes",
max: "#{documentable_class.max_file_size} MB")) max: "#{max_file_size} MB"))
end end
end end
def validate_attachment_content_type def validate_attachment_content_type
if documentable_class && if documentable_class && !accepted_content_types.include?(attachment_content_type)
!accepted_content_types(documentable_class).include?(attachment_content_type)
accepted_content_types = documentable_humanized_accepted_content_types(documentable_class)
message = I18n.t("documents.errors.messages.wrong_content_type", message = I18n.t("documents.errors.messages.wrong_content_type",
content_type: attachment_content_type, content_type: attachment_content_type,
accepted_content_types: accepted_content_types) accepted_content_types: self.class.humanized_accepted_content_types)
errors.add(:attachment, message) errors.add(:attachment, message)
end end
end end

View File

@@ -1,6 +1,4 @@
class Image < ApplicationRecord class Image < ApplicationRecord
include ImageablesHelper
has_attached_file :attachment, styles: { has_attached_file :attachment, styles: {
large: "x#{Setting["uploads.images.min_height"]}", large: "x#{Setting["uploads.images.min_height"]}",
medium: "300x300#", medium: "300x300#",
@@ -30,6 +28,26 @@ class Image < ApplicationRecord
before_save :set_attachment_from_cached_attachment, if: -> { cached_attachment.present? } before_save :set_attachment_from_cached_attachment, if: -> { cached_attachment.present? }
def self.max_file_size
Setting["uploads.images.max_size"].to_i
end
def self.accepted_content_types
Setting["uploads.images.content_types"]&.split(" ") || ["image/jpeg"]
end
def self.humanized_accepted_content_types
Setting.accepted_content_types_for("images").join(", ")
end
def max_file_size
self.class.max_file_size
end
def accepted_content_types
self.class.accepted_content_types
end
def set_cached_attachment_from_attachment def set_cached_attachment_from_attachment
self.cached_attachment = if Paperclip::Attachment.default_options[:storage] == :filesystem self.cached_attachment = if Paperclip::Attachment.default_options[:storage] == :filesystem
attachment.path attachment.path
@@ -77,11 +95,10 @@ class Image < ApplicationRecord
end end
def validate_attachment_size def validate_attachment_size
if imageable_class && if imageable_class && attachment_file_size > max_file_size.megabytes
attachment_file_size > Setting["uploads.images.max_size"].to_i.megabytes
errors.add(:attachment, I18n.t("images.errors.messages.in_between", errors.add(:attachment, I18n.t("images.errors.messages.in_between",
min: "0 Bytes", min: "0 Bytes",
max: "#{imageable_max_file_size} MB")) max: "#{max_file_size} MB"))
end end
end end
@@ -104,7 +121,7 @@ class Image < ApplicationRecord
if imageable_class && !attachment_of_valid_content_type? if imageable_class && !attachment_of_valid_content_type?
message = I18n.t("images.errors.messages.wrong_content_type", message = I18n.t("images.errors.messages.wrong_content_type",
content_type: attachment_content_type, content_type: attachment_content_type,
accepted_content_types: imageable_humanized_accepted_content_types) accepted_content_types: self.class.humanized_accepted_content_types)
errors.add(:attachment, message) errors.add(:attachment, message)
end end
end end
@@ -116,6 +133,6 @@ class Image < ApplicationRecord
end end
def attachment_of_valid_content_type? def attachment_of_valid_content_type?
attachment.present? && imageable_accepted_content_types.include?(attachment_content_type) attachment.present? && accepted_content_types.include?(attachment_content_type)
end end
end end

View File

@@ -1,9 +1,7 @@
shared_examples "document validations" do |documentable_factory| shared_examples "document validations" do |documentable_factory|
include DocumentablesHelper
let!(:document) { build(:document, documentable_factory.to_sym) } let!(:document) { build(:document, documentable_factory.to_sym) }
let!(:maxfilesize) { document.documentable.class.max_file_size } let!(:maxfilesize) { document.max_file_size }
let!(:acceptedcontenttypes) { accepted_content_types(document.documentable.class) } let!(:acceptedcontenttypes) { document.accepted_content_types }
it "is valid" do it "is valid" do
expect(document).to be_valid expect(document).to be_valid

View File

@@ -1,8 +1,6 @@
shared_examples "image validations" do |imageable_factory| shared_examples "image validations" do |imageable_factory|
include ImageablesHelper
let!(:image) { build(:image, imageable_factory.to_sym) } let!(:image) { build(:image, imageable_factory.to_sym) }
let!(:acceptedcontenttypes) { imageable_accepted_content_types } let!(:acceptedcontenttypes) { Image.accepted_content_types }
it "is valid" do it "is valid" do
expect(image).to be_valid expect(image).to be_valid