Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic use of :default_url in Paperclip

I'm trying to configure Paperclip to provide different missing images based on the instance's category attribute. Every category of the object has its own missing image.

This is my first take:

EDIT to add full models:

class Service < ActiveRecord::Base

  attr_accessible :logo, :logo_file_name, :logo_content_type, :logo_file_size, :logo_updated_at

  belongs_to :category, :counter_cache => true

  has_attached_file :logo,
                :path => "/:id-:style-:filename",
                :url  => ":s3_eu_url",
                :default_url => "/logos/:style/#{self.category.name]}.png",
                :styles => { :large => "600x400>",
                             :medium => "300x200>",
                             :small => "100x75>",
                             :thumb => "60x42>" }
end

class Category < ActiveRecord::Base
  attr_accessible nil

  has_many :services
end

In my view, image_tag service.logo.url(:thumb) outputs:

undefined method `category' for #<Class:0x0000010a731620>

Any ideas?

EDIT2:

A working default_url is :default_url => "/logos/:style/missing.png",

SOLUTION:

See my own answer below.

like image 592
dgilperez Avatar asked Oct 16 '11 12:10

dgilperez


3 Answers

You can pass a Proc as :default_url to paperclip. See https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/attachment.rb#L135. Paperclip will call that proc with the Attachment object as a parameter. The Attachment object has an accessor 'instance' that is the ActiveRecord object instance it's attached to. In your case you should have:

  has_attached_file :logo,
            :path => "/:id-:style-:filename",
            :url  => ":s3_eu_url",
            :default_url => lambda { |attach| "/logos/:style/#{attach.instance.category.name]}.png },
            :styles => { :large => "600x400>",
                         :medium => "300x200>",
                         :small => "100x75>",
                         :thumb => "60x42>" }
like image 178
Cristian Bica Avatar answered Nov 04 '22 20:11

Cristian Bica


I found a solution, following this gist and this other question in stackoverflow.

My working solution:

Class Service

  has_attached_file :logo,
            :path => "/:id-:style-:filename",
            :url  => ":s3_eu_url",
            :default_url => :set_default_url_on_category,
            :styles => { :large => "600x400>",
                         :medium => "300x200>",
                         :small => "100x75>",
                         :thumb => "60x42>" }

  private

  def set_default_url_on_category
    "/logos/:style/#{category.name}.png"
  end
end

And an initializer paperclip_default_url_fix.rb

module Paperclip
  module Interpolations
    def self.interpolate(pattern, *args)
      pattern = args.first.instance.send(pattern) if pattern.kind_of? Symbol

      all.reverse.inject(pattern.dup) do |result, tag|
        result.gsub(/:#{tag}/) do |match|
          send(tag, *args)
        end
      end
    end
  end
end
like image 22
dgilperez Avatar answered Nov 04 '22 20:11

dgilperez


There is a nice clean solution on the paperclip wiki now for :url, :path, and :default_url which works a teat.

https://github.com/thoughtbot/paperclip/wiki/Interpolations

like image 9
newtriks Avatar answered Nov 04 '22 21:11

newtriks