web-dev-qa-db-fra.com

Ruby on Rails - Stockage actif - Comment accepter uniquement les formats pdf et doc?

Est-il possible d'ajouter une validation pour n'accepter que les fichiers .pdf et .doc utilisant Active Storage? 

6
Magda Sz.

Actuellement, vous devez écrire votre propre validateur qui examine le type MIME de la pièce jointe:

class Item
  has_one_attached :document

  validate :correct_document_mime_type

  private

  def correct_document_mime_type
    if document.attached? && !document.content_type.in?(%w(application/msword application/pdf))
      errors.add(:document, 'Must be a PDF or a DOC file')
    end
  end
end

De plus, il existe des méthodes de raccourcis utiles image?, audio?, video? et text? qui vérifient plusieurs types MIME.

10
michalvalasek

il y a une gemme qui fournit la validation pour le stockage actif

gem 'activestorage-validator'

https://github.com/aki77/activestorage-validator

  validates :avatar, presence: true, blob: { content_type: :image }
  validates :photos, presence: true, blob: { content_type: ['image/png', 'image/jpg', 'image/jpeg'], size_range: 1..5.megabytes }
5
Confused Vorlon

Comme ActiveStorage n'a pas encore de validations, j'ai trouvé les aides suivantes dans mes formulaires.

<div class="field">
  <%= f.label :deliverable %>
  <%= f.file_field :deliverable, direct_upload: true, 
    accept: 'application/pdf, 
    application/Zip,application/vnd.openxmlformats-officedocument.wordprocessingml.document' %>
 </div>
2
memoht
class Book < ApplicationRecord
  has_one_attached :image
  has_many_attached :documents

  validate :image_validation
  validate :documents_validation

  def documents_validation
    error_message = ''
    documents_valid = true
    if documents.attached?
      documents.each do |document|
        if !document.blob.content_type.in?(%w(application/xls application/odt application/ods pdf application/tar application/tar.gz application/docx application/doc application/rtf application/txt application/rar application/Zip application/pdf image/jpeg image/jpg image/png))
          documents_valid = false
          error_message = 'The document wrong format'
        elsif document.blob.byte_size > (100 * 1024 * 1024) && document.blob.content_type.in?(%w(application/xls application/odt application/ods pdf application/tar application/tar.gz application/docx application/doc application/rtf application/txt application/rar application/Zip application/pdf image/jpeg image/jpg image/png))
          documents_valid = false
          error_message = 'The document oversize limited (100MB)'
        end
      end
    end
    unless documents_valid
      errors.add(:documents, error_message)
      self.documents.purge
      DestroyInvalidationRecordsJob.perform_later('documents', 'Book', self.id)
    end
  end

  def image_validation
    if image.attached?
      if !image.blob.content_type.in?(%w(image/jpeg image/jpg image/png))
        image.purge_later
        errors.add(:image, 'The image wrong format')
      elsif image.blob.content_type.in?(%w(image/jpeg image/jpg image/png)) && image.blob.byte_size > (5 * 1024 * 1024) # Limit size 5MB
        image.purge_later
        errors.add(:image, 'The image oversize limited (5MB)')
      end
    elsif image.attached? == false
      image.purge_later
      errors.add(:image, 'The image required.')
    end
  end
end

Et au travail détruire

class DestroyInvalidationRecordsJob < ApplicationJob
  queue_as :default

  def perform(record_name, record_type, record_id)
    attachments = ActiveStorage::Attachment.where(name: record_name, record_type: record_type, record_id: record_id)
    attachments.each do |attachment|
      blob = ActiveStorage::Blob.find(attachment.blob_id)
      attachment.destroy
      blob.destroy if blob.present?
    end
  end
end
1
Enziin System

Je faisais des téléchargements directs avec ActiveStorage. Comme les validateurs n'existent pas encore, j'ai simplement écrasé la méthode DirectUploadsController Create:

# This is a kind of monkey patch which overrides the default create so I can do some validation.
# Active Storage validation wont be released until Rails 6.
class DirectUploadsController < ActiveStorage::DirectUploadsController
  def create
    puts "Do validation here"
    super
  end
end

également besoin d'écraser l'itinéraire:

  post '/Rails/active_storage/direct_uploads', to: 'direct_uploads#create'
0
Deekor