4

This is the first time I'm using Paperclip and Amazon S3 and I'm pretty sure I'm missing something obvious. It would be great if somebody can point it out.

In S3 bucket, I have 2 folders, development and production, to upload images to corresponding folders based on the environment. I tried the solution proposed here as follows in my model.rb -

options = {}

if Rails.env.production?
   options[:path] ||= 'production'
else
   options[:path] ||= 'development'
end

has_attached_file :picture, options

I kept getting a file named development / production uploaded to the S3 bucket (as shown in the screenshot).

enter image description here

I even tried passing the :path as config setting for paperclip. Same thing happened - a folder named development / production was getting uploaded

Am I missing something here? All I want to do, upload pictures I get in the development environment into the development folder and vice versa for production.

Community
  • 1
  • 1
Aswin Ramakrishnan
  • 3,195
  • 2
  • 41
  • 65

1 Answers1

5

The path option needs to specify the file pattern as well. Try this

Model

has_attached_file :picture,
  :storage => :s3,
  :bucket => 'your_bucket',
  :path => ":env_folder/:attachment/:id/:style/:filename.:extension"

# some other model code here ...

private

# interpolate in paperclip
Paperclip.interpolates :env_folder  do |attachment, style|
  Rails.env.production? ? 'production' : 'development'
end

EDIT

If you just leave the :path option as 'development' or 'production' you're telling Paperclip the path to the file is yourbucket/development which is why you're seeing the single file as per your screenshot. This is why it's important to have something that will uniquely identify the resource in the :path option (I used :id in my example which will use the model's id attribute).

If you have the option, I think a better approach would be to separate the environments into their own buckets. In other words, the development environment would have its own bucket and production would have its own separate bucket. Not only is this cleaner within the code, you'll also be able to set different policies per bucket/environment which in my experience is required once your app is released in production. Hope this helps.

Bart Jedrocha
  • 11,450
  • 5
  • 43
  • 53
  • I don't get why there needs to be an extension in the path. I basically want all the pictures (jpg, png etc.) to be uploaded to that specific folder in my S3 bucket. The path basically specifies the folder structure within the S3 bucket, correct? – Aswin Ramakrishnan Nov 17 '14 at 22:26
  • I agree separating the environments into their own buckets makes it cleaner. But with S3 being so popular, I was wondering if there'd be an easier way to do folder level separation. – Aswin Ramakrishnan Nov 17 '14 at 22:35
  • 1
    @AswinRamakrishnan the `:extension` in my example is just for illustrative purposes, you can omit it if you don't want it as part of the URI. The `path` option specifies the path to the uploaded file which is why you can't just have 'production' or 'development' as in your original post. If you just had 'development' then the actual name of the uploaded file would be 'development' as in your attached screenshot. – Bart Jedrocha Nov 17 '14 at 22:48
  • 1
    @AswinRamakrishnan in regards to popularity and the fact that S3 buckets have to be unique, I found a good solution is to namespace your buckets with your application name. For example, `myapp.prod` and `myapp.development`. – Bart Jedrocha Nov 17 '14 at 22:52
  • 10-4 on the path option! As you can tell - S3 Noob :) I like namespacing the buckets option. Just curious - by namespacing the buckets, do you get any app level isolation? Or is it more of a convention thing? – Aswin Ramakrishnan Nov 17 '14 at 22:57
  • @AswinRamakrishnan it's simply a convention. Please accept my answer if you found it helpful. Cheers. – Bart Jedrocha Nov 17 '14 at 23:09