Paperclip not displaying image (rails api) - ruby-on-rails-5

I have a user module and I have generated paperclip attachment: profile_pic
user.rb:
has_attached_file :profile_pic,
style: { :medium => "300x300>", thumb: "100x100>" },
default_url: "/images/:style/missing.png"
controller:
image_base = params[:manager][:profile_pic]
if image_base != nil
image = Paperclip.io_adapters.for(image_base)
image.original_filename = params[:manager][:file_name]
current_user.profile_pic = image
current_user.errors.delete(:profile_pic)
current_user.save
end
config/initializers/paperclip.rb:
Paperclip::DataUriAdapter.register
It's not showing any errors but If I am trying to display the image, it gives me following error:
ActionController::RoutingError (No route matches [GET] "/system/managers/profile_pics/000/000/008/original/icon_new.png"):
When I am trying in console like:
user.profile_pic.display
/system/managers/profile_pics/000/000/008/original/icon_new.png?
1556082410 => nil
Picture was saved in public folder

The default folder is the following, so Paperclip uploaded to the right place:
:rails_root/public/system/:class/:attachment/:id_partition/:style/:filename
But it looks like you are having troubles accessing the right location. Have you tried user.profile_pic.url? I tried on my working example, both .display and .url are the same but I use an AWS S3 bucket.
user.profile_pic.url should be where to find the file on the web.
user.profile_pic.path should be where to find the file on the file system.

The problem is with production mode and Solved this by adding the following line in production.rb
config.public_file_server.enabled = true

Related

Accept an image via Rails 5 API and Active Storage

I am trying to send images to my Rails app and then store them via Active Storage.
I tried Base64 and direct upload and researched for hours but nothing really works.
Can somebody point me to a good way?
My last attempt was to use Base64 like so:
def attach_preview
page = Page.first
content = JSON.parse(request.body.read)
decoded_data = Base64.decode64(content["file_content"].force_encoding("UTF-8"))
begin
file = Tempfile.new('test')
file.write decoded_data
#page.thumbnail = file
filename = "foooo"
page.thumbnail.attach(io: File.read(file), filename: filename)
if page.save
render :json => {:message => "Successfully uploaded the profile picture."}
else
render :json => {:message => "Failed to upload image"}
end
ensure
file.close
file.unlink
end
end
But this results in a "\xAB" from ASCII-8BIT to UTF-8 error.
Dont really care if its Base64 or something else, I just need a way :-)
This works, I use IO directly since ActiveStorage needs it anyway.
def attach_thumbnail
content = JSON.parse(request.body.read.force_encoding("UTF-8"))
decoded_data = Base64.decode64(content["file_content"])
io = StringIO.new
io.puts(decoded_data)
io.rewind
#page.thumbnail.attach(io: io, filename: 'base.png')
#page.save
render json: {
success: #page.thumbnail.attached?,
thumbnail_url: url_for(#page.thumbnail),
page: #page
}
end

How to set the Content Disposition header with Paperclip / fog for a file hosted on S3?

I'm using Paperclip 4.2.0 and fog 1.24.0, and host files on S3. I want to generate an expiring URL that has the "Content-Disposition" header set to "attachment".
Paperclip has this option to pass additional parameters to S3 expiring URLs but I can't have it working when using Paperclip with Paperclip::Storage::Fog.
This fog issue gives the following solution:
file.url(60.seconds.from_now, { :query => { 'response-content-disposition' => 'attachment' } }
but it does not work for me. My Rails model ResourceDocument has has_attached_file :target. document.target.url(60.seconds.from_now, { :query => { 'response-content-disposition' => 'attachment' } } returns the same URL than document.target.url(60.seconds.from_now), ie no content-disposition is included in the generated URL: "xxx.s3.amazonaws.com/uploads/resource_documents/targets/40/2014-12-01%2017:26:20%20UTC/my_file.csv"
I am using aws-sdk gems and it works fine for me, hope this helpful for you.
gem 'aws-sdk-core'
gem 'aws-sdk'
and model's method:
def download_url
s3 = AWS::S3.new
s3_videos_bucket = 'xxxx' #bucket name goes right here
bucket = s3.buckets[s3_videos_bucket]
object_path = 'xxxx' #file path goes right here
object = bucket.objects[object_path]
object.url_for(:get, {
expires: 60.minutes,
response_content_disposition: 'attachment;'
}).to_s
end

Preventing duplicates when seeding with existing image using Paperclip + Amazon S3

Every time I re-seed my database locally, duplicate images are being created in my Amazon S3 bucket. I think this is happening because I am not seeding correctly, but I don't know the proper way to do it. I've been using the method shown here. I'm using Rails 4, Ruby 2, paperclip 3.5.2, and aws-sdk 1.20.0.
You can see below in my seeds.rb file, I'm trying to set the image to the url of an image that has already been uploaded to the correct folder in my bucket. However, I think using open() here is causing a new, identical file to be saved to the same folder, usually something like http://s3.amazonaws.com/BUCKET_NAME/restaurants/images/1/original/open-uri20131111-22904-xvzitl.?1384211739.
EDIT: so my bucket will have both this file stored as well as http://s3.amazonaws.com/BUCKET_NAME/restaurants/images/1/original/NAME.jpg
Would really appreciate any help!
model
has_attached_file :image,
:styles => { :medium => "300x300>", :thumb => "100x100>" }
seeds.rb
Restaurant.create!( name: ...,
description: ...,
image: open('https://s3.amazonaws.com/<BUCKET NAME>/restaurants/images/1/original/<NAME>.jpg') )
config/initializers/paperclip.rb
Paperclip::Attachment.default_options[:storage] = :s3
Paperclip::Attachment.default_options[:s3_credentials] = {
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
Paperclip::Attachment.default_options[:bucket] = ENV['AWS_BUCKET']
Paperclip::Attachment.default_options[:url] = ":s3_path_url"
Paperclip::Attachment.default_options[:path] = "/:class/:attachment/:id/:style/:basename.:extension"
Paperclip::Attachment.default_options[:default_url] = "https://s3.amazonaws.com/<BUCKET NAME>/images/missing.png"
I'm pretty late to the party on this one but I figure others may still be having the same problem. If you set the attachments on your models to nil before deleting them paperclip will delete them from S3.

Carrierwave resize is not working (Rails 3 and MiniMagick)

what I want to do is to save a website url with a full-size snapshot via IMGKit. In one of the views I also want to have a thumbnail version of the snapshot. I'm using carrierwave in order to associate the snapshot with the object an MiniMagick to manipulate it, the problem is that it generates the 'thumbnail' image but doesn't resize it so as a result, I have two full-size snapshots, one of then with 'thumb' as prefix.
I have this model in rails
class Webpage
mount_uploader :snapshot, SnapshotUploader
field :url, type: String
field :title, type: String
after_create :get_snapshot
private
def get_snapshot
file = Tempfile.new(["#{id}#{title}".downcase, '.jpg'], 'tmp', :encoding => 'ascii-8bit')
image = IMGKit.new(url, quality: 90).to_jpg
file.write(image)
file.flush
self.snapshot= file
self.save
file.unlink
end
end
And I have this in the Uploader in order to create the thumbnail version:
class SnapshotUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
version :thumb do
process resize_to_fill: [180, 180]
end
end
Using the console I tried MiniMagick for resizing an image and it works fine son I don't know what is happening.
I'm not sure if I'm doing it right so any help would be appreciated. Thanks.
OK, I'm stupid. I had an initializer with
config.enable_processing = false
so it will never process the image. Just setting it to true or deleting the line solved my problem.

rails aws-s3 delete file throws AWS::S3::PermanentRedirect error - EU bucket problem?

I'm building a rails3 app on heroku, and I'm using aws-s3 gem to manipulate files stored in an Amazon S3 eu bucket.
When I try to perform a AWS::S3::S3Object.delete filename, 'mybucketname' command, I get the following error:
AWS::S3::PermanentRedirect (The bucket you are attempting to access
must be addressed using the specified endpoint. Please send all future
requests to this endpoint.):
I have added the following to my application.rb file:
AWS::S3::Base.establish_connection!(
:access_key_id => "myAccessKey",
:secret_access_key => "mySecretAccessKey"
)
and the following code to my controller:
def destroy
song = tape.songs.find(params[:id])
AWS::S3::S3Object.delete song.filename, 'mybucket'
song.destroy
respond_to do |format|
format.js { render :nothing => true }
end end
I found a proposed solution somewhere to add AWS_CALLING_FORMAT: SUBDOMAIN to my amazon_s3.yml file, as supposedly, aws-s3 should handle differently eu buckets than us.
However, this did not work, same error is received.
Could you please provide any assistance?
Thank you very much for your help.
the problem is you need to type SUBDOMAIN as uppercase string in config, try this out
You can specify custom endpoint at connection initialization point:
AWS::S3::Base.establish_connection!(
:access_key_id => 'myAccessKey',
:secret_access_key => 'mySecretAccessKey',
:server => 's3-website-us-west-1.amazonaws.com'
)
you can find actual endpoint through the AWS console:
full list of valid options - here https://github.com/marcel/aws-s3/blob/master/lib/aws/s3/connection.rb#L252
VALID_OPTIONS = [:access_key_id, :secret_access_key, :server, :port, :use_ssl, :persistent, :proxy].freeze
My solution is to set the constant to the actual service link at initialization time.
in config/initializers/aws_s3.rb
AWS::S3::DEFAULT_HOST = "s3-ap-northeast-1.amazonaws.com"
AWS::S3::Base.establish_connection!(
:access_key_id => 'access_key_id',
:secret_access_key => 'secret_access_key'
)