JoHksi JoHksi - 4 months ago 15
Ruby Question

Setting URL/PATH correctly for AWS S3 by using Paperclip/Rails

I have two models:

Collection
and
Letter
.
Collection
has many
Letter
s and
Letter
obviously belongs_to
Collection
.

Below is my Letter.rb file:

class Letter < ActiveRecord::Base
belongs_to :collection

has_attached_file :pdf,
:url => "/pdf/:id/:style/:basename.:extension",
:path => "/pdf/:id/:style/:basename.:extension",
:s3_host_name => host_name,
:storage => :s3,
:bucket => ENV['S3_BUCKET_NAME'],
:s3_credentials => {
:access_key_id =>#ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key =>ENV['AWS_SECRET_ACCESS_KEY']
}

validates_attachment :pdf,
:content_type => {
:content_type =>
["application/pdf", "text/plain", /\Aimage\/.*\Z/, "application/msword"]
}

end


I have a question about
url
and
path
attribute in
has_attached_file
.

Instead of setting letter model's id in path, I would like to set collection's id. Additionally, I also wanna put
title
which is Letter's attribute. Let's say
@collection
's id is 1.
@collection
has @letter1 and @letter2. When I save the files to AWS S3, I want to save it under
/pdf/1(which is collection_id)/:title
. How can I write this in
url
and
path
?

Answer

In Paperclip, you can use interpolations for that.

Your has_attached_file method would look somewhat like this;

has_attached_file :image, :default_url => "/pdf/:collection_id/:title/:basename.:extension"

Create an interpolation file, called paperclip.rb or interpolations.rb in the config/initializers directory (rails picks up any script in that folder on startup), which contains code that looks somewhat like this;

Paperclip.interpolates :collection_id do |attachment, style|
    attachment.instance.collection_id
end

Add the :title interpolation in the same way; add it to your has_attached_file urls, and create a second interpolation for that.

You can read more about this at https://github.com/thoughtbot/paperclip/wiki/Interpolations

In your case, I would suggest to also include the :id of the Letter in the URL, as it might be possible the user uploads two documents with the same title which might conflict.

has_attached_file :image, :default_url => "/pdf/:collection_id/:id/:title"

Paperclip uses the interpolations :basename, :extension and :style by default to create a unique path for the file.

  • :basename is the base file name of the uploaded file
  • :extension is the extension of that uploaded file
  • :style is the "style" or size of that uploaded file

You can specify multiple styles (like thumnails in various versions). The default style is "original", which will contain the original uploaded file.

Read more about styles here; https://github.com/thoughtbot/paperclip/wiki/Thumbnail-Generation

Always try to keep the original file as it can be handy in the future; when your site/application layout changes and new thumbnail sizes are required. You can rebuild/regenerate your whole thumbnail library from the original version.

Read more about generating/regenerating thumbnails here; https://github.com/thoughtbot/paperclip/wiki/Thumbnail-Generation#generatingregenerating-your-thumbnails