Skip to content

Instantly share code, notes, and snippets.

@theIV
Created August 6, 2013 16:41
Show Gist options
  • Save theIV/6166224 to your computer and use it in GitHub Desktop.
Save theIV/6166224 to your computer and use it in GitHub Desktop.
# How to use Paperclip for generic attachment types on models in Ruby on Rails
class User < ActiveRecord::Base
has_many :user_assets
end
# example of building a model which is a generic attachment asset
@user.build_user_asset(:asset_type => "podcast", :attached_file => some_uploaded_file_data)
# make a generic asset class, with instances initialized for specific asset
# types through Paperclip
# models/user_asset.rb
class UserAsset < ActiveRecord::Base
belongs_to :users
attr_accessor :attached_file
def setup_attached
opts = ASSETS[asset_type.to_sym].dup
opts[:path] = ":rails_root/public"+opts[:url]
less_than = opts.delete :less_than
content_type = opts.delete :content_type
self.class.has_attached_file :asset, opts
if less_than
self.class.validates_attachment_size :asset, :less_than => less_than
end
if content_type
self.class.validates_attachment_content_type :asset, :content_type => content_type
end
# reach into paperclip, make it setup the attachment at run-time
self.asset.assign(@attached_file) if @attached_file
end
def after_initialize
if !asset_type.nil?
setup_attached
else
raise <<-TXT
Error: UserAsset asset_type is nil, paperclip cannot lookup
ASSET[asset_type]. You forgot to pass :asset_type param to UserAsset
new() or build() ?
TXT
end
end
end
# config/initializers/user_asset.rb
# Unify the Paperclip options for attachments instead of duplicating them
# throughout the models code
ASSET_IMAGE_CONTENT_TYPES = ['image/jpg', 'image/jpeg', 'image/gif', 'image/png', 'image/x-png', 'image/pjpeg']
ASSET_VIDEO_CONTENT_TYPES = [ "audio/mpeg","audio/mpg", "audio/x-mpeg", "audio/mp3","audio/x-mp3","audio/mpeg3","audio/x-mpeg3","audio/x-mpg","audio/x-mpegaudio","video/mp4","video/x-mp4","video/mv4","video/x-mv4","video/m4v","video/x-m4v"]
ASSET_AUDIO_CONTENT_TYPES = ["audio/mpeg","audio/mpg", "audio/x-mpeg", "audio/mp3","audio/x-mp3","audio/mpeg3","audio/x-mpeg3","audio/x-mpg","audio/x-mpegaudio","video/mp4","video/x-mp4","video/mv4","video/x-mv4","video/m4v","video/x-m4v"]
# use the same directory/file structure for all attachments: 0000/0000/file.style.ext
ASSET_INTERPOLATION = ":partition/:basename:.style.:extension"
DEFAULT_IMAGE_ATTACHMENT = {
:less_than => 2.megabytes,
:default_style => :original,
:styles => {:original => "300x600", :thumb => "150x300"},
:content_type => ASSET_IMAGE_CONTENT_TYPES,
:url => "/assets/profile_images/"+ASSET_INTERPOLATION
}
CORP_IMAGE_ATTACHMENT = {
:less_than => 4.megabytes,
:default_style => :medium,
:styles => {:small => "100x100", :medium => "200x200", :large => "300x300"},
:content_type => ASSET_IMAGE_CONTENT_TYPES,
:url => "/assets/corps/items/"+ASSET_INTERPOLATION
}
DEFAULT_PODCAST_ATTACHMENT = {
:less_than => 25.megabytes,
:content_type => ASSET_AUDIO_CONTENT_TYPES,
:url => "/assets/podcasts/"+ASSET_INTERPOLATION
}
ASSETS = {
:media => {:less_than => 100.megabytes,
:url => "/assets/corps/media/"+ASSET_INTERPOLATION},
#no content_type, any type can be uploaded
:podcast => {:less_than => 100.megabytes,
:url => "/assets/users/podcasts/"+ASSET_INTERPOLATION,
:content_type => ASSET_AUDIO_CONTENT_TYPES},
:logo => CORP_IMAGE_ATTACHMENT.merge({:less_than => 5.megabytes,
:url => "/assets/corps/logos/"+ASSET_INTERPOLATION}),
}
## Global paperclip interpolations used by all models having Paperclip attachments
Paperclip::Attachment.interpolations[:partition] = proc do |attachment, style|
("%08d" % attachment.instance.id).scan(/\d{4}/).join("/").to_s
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment