Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Paperclip polymorphic styles

I'm using paperclip for attachments for multiple models using accepts_nested_attributes_for. Is there a way I can specify specific paperclip style options for each model?

like image 504
Randuin Avatar asked Aug 19 '10 01:08

Randuin


2 Answers

Yes. I use single table inheritance (STI) on sites for handling Audio, Video, and Images via an Asset model.

# models/Asset.rb
class Asset < ActiveRecord::Base
  # Asset has to exist as a model in order to provide inheritance
  # It can't just be a table in the db like in HABTM. 
end

# models/Audio.rb
class Audio < Asset # !note inheritance from Asset rather than AR!
  # I only ever need the original file
  has_attached_file :file
end

# models/Video.rb
class Video < Asset
  has_attached_file :file, 
    :styles => {
      :thumbnail => '180x180',
      :ipod => ['320x480', :mp4]
      },
    :processors => "video_thumbnail"
end

# models/Image.rb
class Image < Asset
  has_attached_file :file,
    :styles => {
      :medium => "300x300>", 
      :small => "150x150>",
      :thumb => "40x40>",
      :bigthumb => "60x60>"
    }
end

They all come into Rails as :file, but the controller (A/V/I) knows to save to the proper model. Just remember that all attributes for any of the forms of media need to be included in Asset: if video doesn't need captions but images do, then the caption attribute will be nil for Video. It won't complain.

Associations will also work fine if hooked up to the STI models. User has_many :videos will operate the same as you are using it now, just make sure you don't try to save to Asset directly.

  # controllers/images_controller.rb
  def create
    # params[:image][:file] ~= Image has_attached_file :file
    @upload = current_user.images.build(params[:image]) 
    # ...
  end

Lastly, since you do have an Asset model, you can still read directly from it if e.g. you want a list of the 20 most recent Assets. Also, this example isn't restricted to separating media types, it can be used for different kinds of the same thing as well: Avatar < Asset, Gallery < Asset, and so on.

like image 128
Eric Avatar answered Oct 29 '22 21:10

Eric


A much nicer way can be, (if use are dealing with images):

class Image < ActiveRecord::Base
  belongs_to :imageable, :polymorphic => true
  has_attached_file :attachment, styles: lambda {
    |attachment| { 
      thumb: ( 
        attachment.instance.imageable_type.eql?("Product") ? ["300>", 'jpg'] :  ["200>", 'jpg']   
      ),
      medium: ( 
       ["500>", 'jpg']
      )
    }
  }
end
like image 35
Mohit Jain Avatar answered Oct 29 '22 20:10

Mohit Jain