Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use paperclip to handle multiple file types

How possible is it to use one single paperclip field to handle for different file types. For example, I have a file model with with a paperclip method that says:

has_attached_file :file

This file can be a picture, audio, video, or document.

If it's a picture, how can I make it such that the has_attached_file :file would be able to handle pictures in this way:

has_attached_file :file, styles: {thumb: "72x72#"}

Then if it's other document types, it would work just as normal without the style so I don't have to create fields for different file types.

like image 537
Uchenna Avatar asked Apr 18 '14 19:04

Uchenna


2 Answers

The way you'll handle conditional styling is to use a lambda to determine what type of content you're dealing with. We've done this before with an earlier version of Rails / Paperclip:

#app/models/attachment.rb
Class Attachment < ActiveRecord::Base
    has_attached_file :file,
    styles: lambda { |a| a.instance.is_image? ? {:small => "x200>", :medium => "x300>", :large => "x400>"} : {}}  

    validates_attachment_content_type :file, :content_type => [/\Aimage\/.*\Z/, /\Avideo\/.*\Z/]

    private

    def is_image?
        attachment.instance.attachment_content_type =~ %r(image)
    end
end
like image 120
Richard Peck Avatar answered Oct 10 '22 16:10

Richard Peck


Thanks to Rich Peck's Answer i was able to solve my problem with this solution.

first of all use lambda to handle conditions

  has_attached_file :file,
                    styles: lambda { |a| a.instance.check_file_type}

then i defined a custom method named check_file_type

in this method i did the validations and checking with ease based on this ruby best pratice article

def check_file_type
    if is_image_type?
      {:small => "x200>", :medium => "x300>", :large => "x400>"}
    elsif is_video_type?
      {
          :thumb => { :geometry => "100x100#", :format => 'jpg', :time => 10, :processors => [:ffmpeg] },
          :medium => {:geometry => "250x150#", :format => 'jpg', :time => 10, :processors => [:ffmpeg]}
      }
    else
      {}
    end
  end

and defined my is_image_type? and is_video_type? to handle for both videos and images.

  def is_image_type?
    file_content_type =~ %r(image)
  end

  def is_video_type?
    file_content_type =~ %r(video)
  end

then my attachment validation now looks like this

validates_attachment_content_type :file, :content_type => [/\Aimage\/.*\Z/, /\Avideo\/.*\Z/, /\Aaudio\/.*\Z/, /\Aapplication\/.*\Z/]

with this method, i can now use one paperclip method to handle multiple file types.

like image 34
Uchenna Avatar answered Oct 10 '22 15:10

Uchenna