Can't get Paperclip to set my S3 URLs properly
Asked Answered
M

2

8

I'm using paperclip and aws-sdk gems in a Rails 4 app.

I define the :path option in my paperclip.rb config, with no :url option:

Paperclip::Attachment.default_options[:path] = ":class/:attachment/:id_partition/:style/:filename"

It saves my uploaded images like such:

http://s3.amazonaws.com/mybucket-development/profiles/avatars/000/000/026/original/image_file_name.png?1420575189

All fine, it gets saved to S3. However it refuses to let me read the images for display, e.g. =profile.avatar.url(:medium). When I go to that URL in the browser it tells me to re-format it with the bucket name as a domain. Like:

http://mybucket-development.s3.amazonaws.com/profiles/avatars/000/000/026/original/image_file_name.png?1420575189

OK, not a problem either. I go to that URL, I can view my image. So now I need to figure out how to get Paperclip to format the URLs like this automatically. I read in the Paperclip docs that you just have to set

Paperclip::Attachment.default_options[:url] = ":s3_domain_url"

And that I also have to set the :path parameter or I will just get a Paperclip::Errors::InfiniteInterpolationError.

So I set my config file with both combined:

Paperclip::Attachment.default_options[:path] = ":class/:attachment/:id_partition/:style/:filename"
Paperclip::Attachment.default_options[:url] = ":s3_domain_url"

Not working... I try scrapping the paperclip.rb and putting it in config/environments/* But no matter what I do, it still saves the URLs without the domain with the bucket name in the path.

So two questions:

1) How can I get Paperclip to automatically format the saved URLs in domain style?

2) Or even better, how can I get S3 to accept the non-domain style URLs, the one that Paperclip is currently generating?

EDIT

So, if I add in the s3_host_name option then it saves the URLs domain style. So I have to have all 3 of:

Paperclip::Attachment.default_options[:url] = ':s3_domain_url'
Paperclip::Attachment.default_options[:path] = ":class/:attachment/:id_partition/:style/:filename"
Paperclip::Attachment.default_options[:s3_host_name] = 's3-us-west-2.amazonaws.com'

And it will save my URLs on the model like so:

http://mybucket-development.s3-us-west-2.amazonaws.com/profiles/avatars/000/000/026/original/image_file_name.png%3F1420580224

But now I see that I have a %3F encoding ("?") in the URL which messes it up.

Melodize answered 6/1, 2015 at 20:52 Comment(2)
Did you create a bucket policy in S3 ?Echo
This doesn't answer your question (you answered it below) but I just want to post here as an FYI to anyone who is wondering why they're getting the Paperclip::Errors::InfiniteInterpolationError error: If you try to change the CDN settings for paperclip you'll get the Infinite Interpolation Error unless you set the path attribute explicitly. You can't change the path or your existing assets won't resolve anymore, so you need to set it to the default path setting. For our paperclip version of 4.3.6, this value was: path: ":class/:attachment/:id_partition/:style/:filename"Polybasite
M
14

Alright, so as mentioned in the above update, to get the domain-style URLs to be saved by Paperclip I have to include all 3 of the following in my paperclip.rb:

Paperclip::Attachment.default_options[:url] = ':s3_domain_url'
Paperclip::Attachment.default_options[:path] = ":class/:attachment/:id_partition/:style/:filename"
Paperclip::Attachment.default_options[:s3_host_name] = 's3-us-west-2.amazonaws.com'

I believe there is a related issue from recent gem upgrades, this produces URLs with encodings that won't work on their own.

So in my views I have had to add URI.unescape, such as

=image_tag URI.unescape(profile.avatar.url(:medium))

I could also set a callback on the model to replace the %3F with the "?" before save.

Strange issue with Paperclip... not sure what was going on. First app I've worked on where I encountered that issue.

Melodize answered 6/1, 2015 at 21:46 Comment(1)
This works because you're setting :s3_host_name which overrides the other settings. You can actually remove :url and :path and it still works. I looked at the source code to paperclip today and it doesn't appear to implement the ':s3_domain_url' logic correctly - or at least, it didn't make sense to me.Gilges
O
0

In paperclip.rb

Paperclip::Attachment.default_options[:s3_host_name] = 's3-ap-south-1.amazonaws.com'

In production.rb

config.paperclip_defaults = {
           storage: :s3,
           s3_protocol: :https,
           s3_credentials: {
           bucket: ENV.fetch('S3_BUCKET_NAME'),
           access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'),
           secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'),
           s3_region: ENV.fetch('AWS_REGION')
 }

This pretty much worked well for me with image_tag. It should work for you too.

Orthicon answered 20/2, 2018 at 16:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.