changing model-path for paperclip - ruby-on-rails

I set in an initializer the save-path of paperclip to a new one and everything is fine.
But some attachment-names (like file) are very abstract:
has_attached_file :file, :styles => {
:thumb => "100x100"
}
I want this one within the new save-path, but in a different folder than 'file'. Is that possible, without changing the attachment_name?
For example: Now I'm have something like /save-path/file/thumb, but I want /save-path/my-new-file-name/thumb.

You can manipulate both path and url of the attachment(s) with the Paperclip interpolations. See https://github.com/thoughtbot/paperclip/wiki/interpolations for further reference.

Related

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

I have two models: Collection and Letter. Collection has many Letters 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?
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
Using gem aws-sdk for a ror application for uploading images to s3
Uploading images to a fixed bucket with different folders for each object or application.
The s3 keeps a limitation on the number of buckets creattion whereas there is no
limitation for content inside a bucket.
This code will upload image for a user to s3 using aws-sdk gem. The bucket and the image uploaded are made public
so that the images uploaded are directly accessible. The input it takes is the image complete path
where it is present, folder in which it should be uploaded and user_id for whom it should
be uploaded.
def save_screenshot_to_s3(image_location, folder_name,user_id)
service = AWS::S3.new(:access_key_id => ACCESS_KEY_ID,
:secret_access_key => SECRET_ACCESS_KEY)
bucket_name = "app-images"
if(service.buckets.include?(bucket_name))
bucket = service.buckets[bucket_name]
else
bucket = service.buckets.create(bucket_name)
end
bucket.acl = :public_read
key = folder_name.to_s + "/" + File.basename(image_location)
s3_file = service.buckets[bucket_name].objects[key].write(:file => image_location)
s3_file.acl = :public_read
user = User.where(id: user_id).first
user.image = s3_file.public_url.to_s
user.save
end
Use key = folder_name.to_s + "/" + File.basename(image_location) to customize the path you want to have.

Rails4 + Paperclip: Url and Path not matching

I use paperclip to upload a users avatar. The image is stored correctly in the /public directory. However I cant figure out how I can get the image displayed. I played with the :url and :path settings for about an hour and cant match them in a way the image will be displayed in the browser.
There is always a 'images/localhost' in the GET-requests path that I can not get rid of.
Here is my code:
user.rb
class User < ActiveRecord::Base
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "missing.png",
:url => ':class/:id/:style.:extension',
:path => ':url'
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
The path in the html-tag looked up by the request looks like this:
<img alt="Original" src="/images/localhost/users/1/original.png?1405249849" />
The correct request which returns the image would be
http://localhost:3000/users/1/original.png?1405248482.
How can I get the request match the correct file-system-path. Or: what is wrong with my settings?
I didnt change the application.rb or the development.rb
Best regards,
Kev
you should take url or path helpers of paperclip wherever possible. So to show the image use:
<%= image_tag #user.avatar.url(:medium) %>
Then:
the image url isn't a file system path. Depending on the storage you use in paperclip, images can reside in different places, see understanding storage of the paperclip gem.
If you use file storage, the files are store somewhere like
public/system/users/avatar/000/000/013/small/my_pic.png
Timestamp
What you're seeing is Paperclip's timestamp - the last time the file / object was updated.
Although I can't find any official reference to this number, it basically allows you to determine which files you're dealing with. According to the question referenced above, it's apparently there for if you want to ensure your visitors see the latest version of the file (IE never gets stored in the cache)
I'm not sure why there is a disparity between your stored image & your path. However, I would say the path is correct; you just need to be able to
--
Bottom line - if your image shows on the page, I don't think there's any systemic issue with your path; if it doesn't show on the page, can you provide logs / reference to the error?
This post, https://stackoverflow.com/a/26222093/1949363, which pointed to http://www.bwigg.com/2009/10/paperclip-customizing-paths-and-urls/ was the answer for me. I was having issues only in my test environment but I believe the fix should work in other environments as well.
Try the following settings:
:path => "public/system/:class/:id/:filename",
:url => "/system/:class/:id/:basename.:extension"

Rails Paperclip dynamic styles - avoid scaling SVG

I want to provide my styles parameter with some lambda that checks if the file is an SVG file, scale it properly or not at all, I would like to communicate with the model as I do with all my other images, as when i render them (#image.image(:thumb). Is this possible?
Right now I attach my file as:
has_mongoid_attached_file :image,
:path => 'app/assets/images/library/:id/:style.:extension',
:styles => {:thumb => "216x162#", :medium => "400x300#", :scenario => "700x525#"},
:url => '/assets/library/:id/:style.:extension'
I've read about dynamic styles and did some trial and error with not success. My thought was that someone perhaps already have done this.
correct me if I misunderstood your question.
Please check https://github.com/thoughtbot/paperclip#dynamic-styles which says you can provide an lambda with attachment as argument of this lambda.
Inside the block you can use attachment.instance.#{any instance method of model}.

How to get image to show using s3 and paperclip?

I am using paperclip and AWS for my Rails app to upload image. You can find it here: http://lit-stream-6263.herokuapp.com/
When I try to upload images, I don't get an error but for some reason the image doesn't show. When I go into the S3 bucket though, I'm able to see the image that gets uploaded...it's just not rendering in the html page. Any advice on how to fix this?
Update
From 9nonnatus, I'm seeing the picture if I change the URL. However in my rails view I have
<%= image_tag product.avatar.url(:medium) %>
to display the image. This is what I see in the documentation as well. How do I adjust this to fit the url you mention above?
class Product < ActiveRecord::Base
attr_accessible :blog_link, :blog_name, :description, :image_link, :name, :num_likes, :product_link, :avatar
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
end
Looking at the source of the page you can copy the image link and try to access it in your browser. It gives an error telling you that your hyperlinks are incorrectly formatted. Instead of making the img src format something like:
http://s3.amazonaws.com/rockywolfugc/products/avatars/000/000/003/medium/59577_10100258833612183_1508749_n.jpg?1386876682
you have to use this format:
http://rockywolfugc.s3-us-west-2.amazonaws.com/products/avatars/000/000/003/medium/59577_10100258833612183_1508749_n.jpg?1386876682
In other words, remove /rockywolfugc from after .com and replace s3 with rockywolfugc.s3-us-west-2
Hope that helps.

Hide the original file (paperclip)

Makes loading custom images, after downloading put a watermark. Paperclip by default puts the files in a folder called styles, such as original, thumb, medium, etc.
I want to hide the original file that is uploaded without a watermark, and leave the original size is available but only with a watermark.
Remove loadable file is not an option, they are needed for the archive.
I want a file kept in the same place and at the same time was not available unauthorized user? For example, a site administrator could view these files, and users could not.
Can cancan restrict access if someone will turn to the original file, the direct link?
try but I'm not sure
has_attached_file :avatar, {
:url => "/system/:hash.:extension",
:hash_secret => "longSecretString"
}
I use
Paperclip.interpolates :maybe_public do |attachment, style|
style == :original ? "private" : "public"
end
has_attached_file :image, :path => ":rails_root/:maybe_public/..."
And it's worked

Resources