Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
S3 headers can be set as a proc now
Browse files Browse the repository at this point in the history
  • Loading branch information
iltempo authored and Jon Yurek committed Jan 9, 2012
1 parent f56e863 commit 7a8d1e6
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
4 changes: 3 additions & 1 deletion lib/paperclip/storage/s3.rb
Expand Up @@ -98,7 +98,9 @@ def self.extended base
(permission == :public_read) ? 'http' : 'https'
end
@s3_metadata = @options[:s3_metadata] || {}
@s3_headers = (@options[:s3_headers] || {}).inject({}) do |headers,(name,value)|
@s3_headers = @options[:s3_headers] || {}
@s3_headers = @s3_headers.call(instance) if @s3_headers.is_a?(Proc)

This comment has been minimized.

Copy link
@m4n

m4n Jan 10, 2012

I have the following use case for the new :s3_headers can be set as a Proc feature. Given the following models

class Band < ActiveRecord::Base
  has_many :songs
  attr_accessible :name
end

class Song < ActiveRecord::Base
  belongs_to :band
  attr_accessible :title, :audio
  has_attached_file :audio, :storage => :s3, :s3_credentials => ...,
    :s3_headers => Proc.new { |song| { 'Content-Disposition' => "attachment; filename=\"#{song.download_filename}\"" } }

  def download_filename
    "#{artist.name} - #{song.title}.mp3"
  end
end

When I create a new song like this

band = Band.first
band.songs.create! :title => "Test", :audio => open("test.mp3")

it fails with NoMethodError: undefined method 'name' for nil:NilClass in Song#download_filename because the artist association is not set at the time the Proc gets called by Paperclip.

In order to fix this, I would like to recommend calling the Proc at a later time. Maybe in the flush_writes method?

@s3_headers = (@s3_headers).inject({}) do |headers,(name,value)|
case name.to_s
when /^x-amz-meta-(.*)/i
@s3_metadata[$1.downcase] = value
Expand Down
49 changes: 49 additions & 0 deletions test/storage/s3_test.rb
Expand Up @@ -940,4 +940,53 @@ def counter

end
end

context "An attachment with S3 storage and metadata set using a proc as headers" do
setup do
rebuild_model(
:storage => :s3,
:bucket => "testing",
:path => ":attachment/:style/:basename.:extension",
:styles => {
:thumb => "80x80>"
},
:s3_credentials => {
'access_key_id' => "12345",
'secret_access_key' => "54321"
},
:s3_headers => lambda {|attachment|
{'Content-Disposition' => "attachment; filename=\"#{attachment.name}\""}
}
)
end

context "when assigned" do
setup do
@file = File.new(fixture_file('5k.png'), 'rb')
@dummy = Dummy.new
@dummy.stubs(:name => 'Custom Avatar Name.png')
@dummy.avatar = @file
end

teardown { @file.close }

context "and saved" do
setup do
[:thumb, :original].each do |style|
object = stub
@dummy.avatar.stubs(:s3_object).with(style).returns(object)
object.expects(:write).with(anything,
:content_type => "image/png",
:acl => :public_read,
:content_disposition => 'attachment; filename="Custom Avatar Name.png"')
end
@dummy.save
end

should "succeed" do
assert true
end
end
end
end
end

0 comments on commit 7a8d1e6

Please sign in to comment.