dgilperez
dgilperez

Reputation: 10796

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.

Upvotes: 11

Views: 15201

Answers (4)

dgilperez
dgilperez

Reputation: 10796

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

Upvotes: 22

newtriks
newtriks

Reputation: 1454

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

Upvotes: 9

Cristian Bica
Cristian Bica

Reputation: 4117

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>" }

Upvotes: 9

bricker
bricker

Reputation: 8941

You don't need self:

:default_url => "/logos/:style/#{category.name}.png",

Upvotes: 0

Related Questions