Rails 3: Trouble uploading image files with Carrierwave/Minimagick - ruby-on-rails-3

I've been getting some trouble lately when uploading files with Carrierwave/Minimagick. When I upload an image file (which is to be processed by Minimagick) I get this kind of error:
No such file or directory - identify -ping /tmp/mini_magick20130202-16398-ph54gr.jpg
This didn't use to happen in my app. Files which are not images give me trouble at all. This is my image uploader file:
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
...
version :small do
process :resize_to_fit => [300, 100]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png)
end
end
I found out that not requesting a version of the image, no error happens (but I don't get the version).

Related

Access CarrierWave image url using SQL in Rails migration

I'm working on a small app that uses CarrierWave for image uploading, but (for reasons that are a bit long and not really relevant) we have to stop using CarrierWave and start uploading images with our own custom requests to different cloud storage services.
But I still need to have the URLs to images that were already uploaded using CarrierWave, and I won't have access to the image_url method once I unmount the CarrierWave uploader, so I want to save all the urls to a new column on my model, and to have that migration be as optimized as possible.
I've searched for ways to access directly the url from the database (I mean, CarrierWave has to store that somewhere) but no luck so far.
I could do something like this (business_image is the column that the uploader is mounted on, image_url is the new column where I want to store the url):
def change
add_column :business_cards, :image_url, :string
BusinessCard.all.each do |bc|
bc.update(image_url: bc.business_image_url)
end
end
But that is obviously not optimized at all since it loads all business cards and updates them one by one. Is there a way to do it in a single SQL statement?
(I'm using Rails 5.1.4, PostgreSQL 10.3 and carrierWave 1.2.1)
One way would be too use batch function and update record in batches, you can use transaction so that if there are any errors the changes would be rolled back.
def change
add_column :business_cards, :image_url, :string
BusinessCard.find_each(batch_size: xxx) do |bc|
ActiveRecord::Base.transaction do
bc.update(image_url: bc.business_image_url)
rescue => e
raise ActiveRecord::Rollback
end
end
end
Hope it helps!!

How to generate PDF in Rails 5 Grape API endpoint and send in response?

I am using rails 5 and grape gem for building my application. Now I have a requirement of generating a PDF and send back to the response using grape endpoint. I am using wicked_pdf gem and wkhtmltopdf-binary for generate PDF. But I am facing the issue of undefined method 'render_to_string'.
I have tried various way to resolve it. but couldn't find any solution.
Below is my code snippet
API Endpoint:
module Endpoints
class GeneratePdf < Grape::API
get do
users = User.all # I want this users list in my PDF
pdf = WickedPdf.new.pdf_from_string(render_to_string('users/index.html.erb')) # placed in app/views/users/pdf.html.erb
# some code here for send pdf back to response
end
end
end
Gemfile:
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
Config > initializers > mime_types.rb
Mime::Type.register "application/pdf", :pdf
Grape::API, don't have a render_to_string method that you can call on it, unlike a typical Rails controller. You should be able to replace that with something similar to this:
require 'erb'
binding_copy = binding
binding_copy.local_variable_set(users: User.all)
template = File.open(Rails.root.join('app/views/users/index.html.erb))
string = ERB.new(template).result(binding_copy)
pdf = WickedPdf.new.pdf_from_string(string)

undefined method `send_data' for main:Object

I am trying to download the data stored amazon s3 bucket using paperclip and aws-sdk gem. Object is publicly accessible.
I am having a method in my controller where I intend do download the data directly.
def method_where_downloading_happens
code for finding url from params
send_file "ModelName.attached_file.url"
end
#Tried both with static and dynamic url.
I am getting following error
NoMethodError: undefined method `send_file for main:Object
However if I use :-
send_file open(ModelName.attached_file.url)
Then a file is downloaded but it's format is binary i.e. windows can't identify the file_type.
Please help how do I provide direct download when the person hits the link.
You can try this:
#In your environment.rb require 'open-uri'
require 'open-uri'
#As send_data will work in controller, so in your controller
def index
data = open(params[:file])
send_data data, :filename => params[:name], ...
end

Removing Carrierwave previously uploaded file messes up new file processing

I'm using https://github.com/jnicklas/carrierwave with AWS3 to upload my app file to Amazon. I've got an Employee model with an image column (think of it as the employee profile picture) which has an uploader mounted to it:
class Employee < ActiveRecord::Base
mount_uploader :image, ProfileImageUploader
...
end
Whenever an employee updates its profile picture, I want the previous one to be deleted. In order to do this, I've got the following :after_update callback in my Employee model:
class Employee < ActiveRecord::Base
...
after_update :remove_changed_image, :if => 'self.image_changed?'
def remove_changed_image
self.image_was.remove!
end
end
This successfully deletes the previous file. But I'm also processing the pictures that get uploaded. In my Uploder I have the following:
class ProfileImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_limit => [300, 300]
end
...
end
The problem is that the new files are not being processed at all. Only one version, the unprocessed one, gets uploaded, whereas if I don't remove the previous image, then all works as it should (many versions are uploaded).
Any help? Thanks!
The problem is with the after_update callback. It is called after the object is saved, thus deleting the newly attached file. You need to call #employee.remove_image before saving the object.

How to print the filename passed to `require`?

When starting the Rails 3.x server (rails s), is it possible to print the path and name of each file as it is being loaded?
Something like below, but for every file that is required by Rails (think loading of each railtie, for example):
Loading boot.rb...
Loading application.rb...
Loading environment.rb...
Loading development.rb...
Loading routes.rb...
Note that I am able to do the above simply by using puts calls in the files above, but that is not what I am aiming for. Instead I would like to print the file name being required by any code, not just in my application but whenever require is called. For example, printing file names for calls to require being made inside the Rails code.
UPDATE
Thanks #ScottJShea. I used the following code:
In application.rb:
require File.expand_path('../boot', __FILE__)
module Kernel
def require_and_print(string)
puts string
require_original(string)
end
alias_method :require_original, :require
alias_method :require, :require_and_print
end
....
Looks like you would need to edit kernel.rb. Here is an SO Post about it where the responder suggests this (although you may ant to limit it to the require method):
module Kernel
def load_and_print(string)
$:.each do |p|
if File.exists? File.join(p, string)
puts File.join(p, string)
break
end
end
load_original(string)
end
alias_method :load_original, :load
alias_method :load, :load_and_print
end