Add arguments to documentable concern to make it configurable for any recipient model.
This commit is contained in:
@@ -7,13 +7,14 @@ class Budget
|
||||
include Reclassification
|
||||
include Followable
|
||||
include Documentable
|
||||
documentable max_documents_allowed: 3,
|
||||
max_file_size: 3.megabytes,
|
||||
accepted_content_types: [ "application/pdf" ]
|
||||
|
||||
acts_as_votable
|
||||
acts_as_paranoid column: :hidden_at
|
||||
include ActsAsParanoidAliases
|
||||
|
||||
MAX_DOCUMENTS_SIZE = 3
|
||||
|
||||
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||
belongs_to :heading
|
||||
belongs_to :group
|
||||
|
||||
@@ -5,4 +5,16 @@ module Documentable
|
||||
has_many :documents, as: :documentable, dependent: :destroy
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
attr_reader :max_documents_allowed, :max_file_size, :accepted_content_types
|
||||
|
||||
private
|
||||
|
||||
def documentable(options= {})
|
||||
@max_documents_allowed = options[:max_documents_allowed]
|
||||
@max_file_size = options[:max_file_size]
|
||||
@accepted_content_types = options[:accepted_content_types]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -4,12 +4,36 @@ class Document < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
belongs_to :documentable, polymorphic: true
|
||||
|
||||
validates_attachment :attachment, presence: true,
|
||||
content_type: { content_type: "application/pdf" },
|
||||
size: { in: 0..3.megabytes }
|
||||
validates_attachment :attachment, presence: true
|
||||
do_not_validate_attachment_file_type :attachment
|
||||
validate :validate_attachment_content_type
|
||||
|
||||
validate :validate_attachment_size
|
||||
validates :title, presence: true
|
||||
validates :user, presence: true
|
||||
validates :documentable_id, presence: true
|
||||
validates :documentable_type, presence: true
|
||||
|
||||
def validate_attachment_size
|
||||
if attachment.file? && documentable.present? && attachment_file_size > documentable.class.max_file_size
|
||||
errors[:attachment] = I18n.t("documents.errors.messages.in_between",
|
||||
min: "0 Bytes",
|
||||
max: "#{bytesToMeg(documentable.class.max_file_size)} MB")
|
||||
end
|
||||
end
|
||||
|
||||
def validate_attachment_content_type
|
||||
if attachment.file? && documentable.present? && !documentable.class.accepted_content_types.include?(attachment_content_type)
|
||||
errors[:attachment] = I18n.t("documents.errors.messages.content_type",
|
||||
content_type: attachment_content_type,
|
||||
accepted_content_types: documentable.class.accepted_content_types.join(", "))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def bytesToMeg bytes
|
||||
bytes / (1024.0 * 1024.0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -10,12 +10,14 @@ class Proposal < ActiveRecord::Base
|
||||
include Graphqlable
|
||||
include Followable
|
||||
include Documentable
|
||||
documentable max_documents_allowed: 3,
|
||||
max_file_size: 3.megabytes,
|
||||
accepted_content_types: [ "application/pdf" ]
|
||||
|
||||
acts_as_votable
|
||||
acts_as_paranoid column: :hidden_at
|
||||
include ActsAsParanoidAliases
|
||||
|
||||
MAX_DOCUMENTS_SIZE = 3
|
||||
RETIRE_OPTIONS = %w(duplicated started unfeasible done other)
|
||||
|
||||
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="small-12 medium-9 column">
|
||||
<%= back_link_to budget_investments_path(investment.budget, heading_id: investment.heading) %>
|
||||
|
||||
<% if can?(:create, @document) && investment.documents.size < Budget::Investment::MAX_DOCUMENTS_SIZE %>
|
||||
<% if can?(:create, @document) && investment.documents.size < Budget::Investment.max_documents_allowed %>
|
||||
<%= link_to t("documents.upload_document"),
|
||||
new_document_path(documentable_id:investment, documentable_type: investment.class.name, from: request.url),
|
||||
class: 'button hollow float-right' %>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<div class="tabs-panel" id="tab-documents">
|
||||
<%= render 'documents/documents',
|
||||
documents: @investment.documents,
|
||||
max_documents_size: Budget::Investment::MAX_DOCUMENTS_SIZE %>
|
||||
max_documents_allowed: Budget::Investment.max_documents_allowed %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<% if documents.any? %>
|
||||
|
||||
<% if documents.size == max_documents_size %>
|
||||
<% if documents.size == max_documents_allowed %>
|
||||
<div class="row documents-list">
|
||||
<div class="small-12 column">
|
||||
<div class="callout primary text-center">
|
||||
<%= t "documents.max_documents_size_reached" %>
|
||||
<%= t "documents.max_documents_allowed_reached" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="small-12 medium-9 column">
|
||||
<%= back_link_to %>
|
||||
|
||||
<% if can?(:create, @document) && @proposal.documents.size < Proposal::MAX_DOCUMENTS_SIZE %>
|
||||
<% if can?(:create, @document) && @proposal.documents.size < Proposal.max_documents_allowed %>
|
||||
<%= link_to t("documents.upload_document"),
|
||||
new_document_path(documentable_id: @proposal, documentable_type: @proposal.class.name, from: request.url),
|
||||
class: 'button hollow float-right' %>
|
||||
@@ -166,6 +166,6 @@
|
||||
<div class="tabs-panel" id="tab-documents">
|
||||
<%= render 'documents/documents',
|
||||
documents: @proposal.documents,
|
||||
max_documents_size: Proposal::MAX_DOCUMENTS_SIZE %>
|
||||
max_documents_allowed: Proposal.max_documents_allowed %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ en:
|
||||
tab: Documents
|
||||
no_documents: Don't have uploaded documents
|
||||
upload_document: Upload document
|
||||
max_documents_size_reached: You have reached the maximum number of documents allowed! You have to delete one before you can upload another.
|
||||
max_documents_allowed_reached: You have reached the maximum number of documents allowed! You have to delete one before you can upload another.
|
||||
form:
|
||||
attachment_label: Choose attachment file
|
||||
submit_button: Upload document
|
||||
@@ -24,3 +24,7 @@ en:
|
||||
download_document: Download PDF
|
||||
destroy_document: Destroy
|
||||
link_document: Link
|
||||
errors:
|
||||
messages:
|
||||
in_between: must be in between %{min} and %{max}
|
||||
wrong_content_type: content type %{content_type} does not match any of accepted content types %{accepted_content_types}
|
||||
@@ -3,7 +3,7 @@ es:
|
||||
tab: Documentos
|
||||
no_documents: No hay documentos subidos
|
||||
upload_document: Subir documento
|
||||
max_documents_size_reached: ¡Has alcanzado el número máximo de documentos permitidos! Tienes que eliminar uno antes de poder subir otro.
|
||||
max_documents_allowed_reached: ¡Has alcanzado el número máximo de documentos permitidos! Tienes que eliminar uno antes de poder subir otro.
|
||||
form:
|
||||
attachment_label: Selecciona un archivo
|
||||
submit_button: Subir documento
|
||||
@@ -24,3 +24,7 @@ es:
|
||||
download_document: Descargar PDF
|
||||
destroy_document: Eliminar
|
||||
link_document: Enlace
|
||||
errors:
|
||||
messages:
|
||||
in_between: debe estar entre %{min} y %{max}
|
||||
wrong_content_type: El tipo de contenido %{content_type} del archivo no coincide con ninguno de los tipos de contenido aceptados %{accepted_content_types}
|
||||
@@ -1,6 +1,8 @@
|
||||
shared_examples "document validations" do |documentable_factory|
|
||||
|
||||
let(:document) { build(:document, documentable_factory.to_sym) }
|
||||
let(:document) { build(:document, documentable_factory.to_sym) }
|
||||
let(:max_file_size) { document.documentable.class.max_file_size }
|
||||
let(:accepted_content_types) { document.documentable.class.accepted_content_types }
|
||||
|
||||
it "should be valid" do
|
||||
expect(document).to be_valid
|
||||
@@ -18,17 +20,20 @@ shared_examples "document validations" do |documentable_factory|
|
||||
expect(document).to_not be_valid
|
||||
end
|
||||
|
||||
it "should not be valid for attachment images" do
|
||||
document.attachment = File.new("spec/fixtures/files/logo_header.png")
|
||||
it "should be valid for all accepted content types" do
|
||||
accepted_content_types.each do |content_type|
|
||||
extension = content_type.split("/").last
|
||||
document.attachment = File.new("spec/fixtures/files/empty.#{extension}")
|
||||
|
||||
expect(document).to_not be_valid
|
||||
expect(document).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
it "should not be valid for attachment 3MB" do
|
||||
document.stub(:attachment_file_size).and_return(3.1.megabytes)
|
||||
it "should not be valid for attachments larger than documentable max_file_size definition" do
|
||||
document.stub(:attachment_file_size).and_return(max_file_size.bytes + 1.byte)
|
||||
|
||||
document.should_not be_valid
|
||||
expect(document.errors[:attachment]).to include "must be in between 0 Bytes and 3 MB"
|
||||
expect(document).to_not be_valid
|
||||
expect(document.errors[:attachment]).to include "must be in between 0 Bytes and #{bytesToMeg(max_file_size)} MB"
|
||||
end
|
||||
|
||||
it "should not be valid without a user_id" do
|
||||
@@ -50,3 +55,7 @@ shared_examples "document validations" do |documentable_factory|
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def bytesToMeg(bytes)
|
||||
bytes / (1024.0 * 1024.0)
|
||||
end
|
||||
Reference in New Issue
Block a user