Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add support for custom Paperclip mappings

Paperclip supports custom interpolations in images' paths. In order to
ease transition into CarrierWave, support the same functionality with the
`Paperclip::Compatibility` module.

The public api is similar to Paperclip's

```ruby
class CustomUploader < CarrierWave::Uploader::Base
  include CarrierWave::Compatibility::Paperclip

  interpolate :some_method do |custom, style|
    custom.model.some_method
  end
end
```

This is accomplished by appending the desired functionality into
`CarrierWave::Compatibility::Paperclip#mappings`
  • Loading branch information...
commit dcb65a90f44382400a8418c60a7ae5419667a368 1 parent 10df389
@Robovirtuoso Robovirtuoso authored Acumen Workstation committed
View
48 lib/carrierwave/compatibility/paperclip.rb
@@ -46,11 +46,31 @@ module Compatibility
# THE SOFTWARE.
#
module Paperclip
+ extend ActiveSupport::Concern
+
+ DEFAULT_MAPPINGS = {
+ :rails_root => lambda{|u, f| Rails.root.to_s },
+ :rails_env => lambda{|u, f| Rails.env },
+ :id_partition => lambda{|u, f| ("%09d" % u.model.id).scan(/\d{3}/).join("/")},
+ :id => lambda{|u, f| u.model.id },
+ :attachment => lambda{|u, f| u.mounted_as.to_s.downcase.pluralize },
+ :style => lambda{|u, f| u.paperclip_style },
+ :basename => lambda{|u, f| u.filename.gsub(/#{File.extname(u.filename)}$/, "") },
+ :extension => lambda{|u, d| File.extname(u.filename).gsub(/^\.+/, "")},
+ :class => lambda{|u, f| u.model.class.name.underscore.pluralize}
+ }
+
+ included do
+ attr_accessor :filename
+ class_attribute :mappings
+ self.mappings ||= DEFAULT_MAPPINGS.dup
+ end
def store_path(for_file=filename)
path = paperclip_path
+ self.filename = for_file
path ||= File.join(*[store_dir, paperclip_style.to_s, for_file].compact)
- interpolate_paperclip_path(path, for_file)
+ interpolate_paperclip_path(path)
end
def store_dir
@@ -68,28 +88,18 @@ def paperclip_style
version_name || paperclip_default_style
end
- private
-
- def interpolate_paperclip_path(path, filename)
- mappings.inject(path) do |agg, pair|
- agg.gsub(":#{pair[0]}") { pair[1].call(self, filename).to_s }
+ module ClassMethods
+ def interpolate(sym, &block)
+ mappings[sym] = block
end
end
- def mappings
- [
- [:rails_root , lambda{|u, f| Rails.root }],
- [:rails_env , lambda{|u, f| Rails.env }],
- [:class , lambda{|u, f| u.model.class.name.underscore.pluralize}],
- [:id_partition , lambda{|u, f| ("%09d" % u.model.id).scan(/\d{3}/).join("/")}],
- [:id , lambda{|u, f| u.model.id }],
- [:attachment , lambda{|u, f| u.mounted_as.to_s.downcase.pluralize }],
- [:style , lambda{|u, f| u.paperclip_style }],
- [:basename , lambda{|u, f| f.gsub(/#{File.extname(f)}$/, "") }],
- [:extension , lambda{|u, f| File.extname(f).gsub(/^\.+/, "")}]
- ]
+ private
+ def interpolate_paperclip_path(path)
+ mappings.each_pair.inject(path) do |agg, pair|
+ agg.gsub(":#{pair[0]}") { pair[1].call(self, self.paperclip_style).to_s }
+ end
end
-
end # Paperclip
end # Compatibility
end # CarrierWave
View
88 spec/compatibility/paperclip_spec.rb
@@ -13,9 +13,17 @@ module Rails; end unless defined?(Rails)
Rails.stub(:env).and_return('test')
@uploader_class = Class.new(CarrierWave::Uploader::Base) do
include CarrierWave::Compatibility::Paperclip
+
+ version :thumb
+ version :list
+
end
+
@model = mock('a model')
@model.stub!(:id).and_return(23)
+ @model.stub!(:ook).and_return('eek')
+ @model.stub!(:money).and_return('monkey.png')
+
@uploader = @uploader_class.new(@model, :monkey)
end
@@ -47,6 +55,86 @@ module Rails; end unless defined?(Rails)
@uploader.stub!(:paperclip_path).and_return("/foo/:id_partition/bar")
@uploader.store_path("monkey.png").should == "/foo/000/000/023/bar"
end
+
+ it "should interpolate the basename" do
+ @uploader.stub!(:paperclip_path).and_return("/foo/:basename/bar")
+ @uploader.store_path("monkey.png").should == "/foo/monkey/bar"
+ end
+
+ it "should interpolate the extension" do
+ @uploader.stub!(:paperclip_path).and_return("/foo/:extension/bar")
+ @uploader.store_path("monkey.png").should == "/foo/png/bar"
+ end
+
end
+ describe '.interpolate' do
+ before do
+ @uploader_class.interpolate :ook do |custom, style|
+ custom.model.ook
+ end
+
+
+ @uploader_class.interpolate :aak do |model, style|
+ style
+ end
+ end
+
+ it 'should allow you to add custom interpolations' do
+ @uploader.stub!(:paperclip_path).and_return("/foo/:id/:ook")
+ @uploader.store_path("monkey.png").should == '/foo/23/eek'
+ end
+
+ it 'mimics paperclips arguments' do
+ @uploader.stub!(:paperclip_path).and_return("/foo/:aak")
+ @uploader.store_path("monkey.png").should == '/foo/original'
+ end
+
+ context 'when multiple uploaders include the compatibility module' do
+ before do
+ @uploader_class_other = Class.new(CarrierWave::Uploader::Base) do
+ include CarrierWave::Compatibility::Paperclip
+
+ version :thumb
+ version :list
+ end
+
+ @uploader = @uploader_class_other.new(@model, :monkey)
+ end
+
+ it 'should not share custom interpolations' do
+ @uploader.stub!(:paperclip_path).and_return("/foo/:id/:ook")
+ @uploader.store_path('monkey.jpg').should == '/foo/23/:ook'
+ end
+
+ end
+
+ context 'when there are multiple versions' do
+ before do
+ @complex_uploader_class = Class.new(CarrierWave::Uploader::Base) do
+ include CarrierWave::Compatibility::Paperclip
+
+ interpolate :ook do |model, style|
+ 'eek'
+ end
+
+ version :thumb
+ version :list
+
+ def paperclip_path
+ "#{public_path}/foo/:ook/:id/:style"
+ end
+ end
+
+ @uploader = @complex_uploader_class.new(@model, :monkey)
+ end
+
+ it 'should interpolate for all versions correctly' do
+ @file = File.open(file_path('test.jpg'))
+ @uploader.store!(@file)
+ @uploader.thumb.path.should == "#{public_path}/foo/eek/23/thumb"
+ @uploader.list.path.should == "#{public_path}/foo/eek/23/list"
+ end
+ end
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.