Command lind to recreate versions in Carrierwave? - ruby-on-rails

If I'm adding a new version in carrierwave, what is the command line to recreate the images if I already have existing images?
What would it be for localhost and for production if I'm using Heroku?
Thanks!

Seems like you want to resize existing images.
You have to add you new version to the image uploader(taking 200*200 thumb as an example)
version :thumb do
process :resize_to_fill => [200,200]
end
Then recreate them in console (taking avatar in User model as an example):
User.all.each do |user|
user.avatar.recreate_versions!
end
UPDATE
If you want to use a custom rake task, you can create a file lib/tasks/resize_image.rake and put the following code in this file:
namespace :resize_image do
desc "RESIZE"
task :recreate => :environment do
User.all.each do |user|
user.avatar.recreate_versions!
end
end
end
And in your console use:
rake resize_image:recreate

Related

Carrierwave Cannot update a database to correct value after calling recreate_versions

I am trying to reprocess all image uploads in my Rails app which uses Carrierwave as I have added a new image version. Looking at the documentation and other examples I found online I created a rake file with the following code:
namespace :reprocess_user_photo do
desc "RESIZE"
task :recreate => :environment do
User.all.each do |user|
if user.photo?
puts user.photo_url
user.photo.cache_stored_file!
user.photo.retrieve_from_cache!(user.photo.cache_name)
user.photo.recreate_versions!
puts user.photo_identifier
user.update_column(:photo, File.basename(user.photo_url))
user.save!
puts user.photo_identifier
end
rescue => e
puts "ERROR: User: #{user.id} -> #{e.to_s}"
end
end
end
This has the output of the following:
/uploads/user/photo/2/1f99e6711141ef7ee2a516db9a197e87.jpg
1f99e6711141ef7ee2a516db9a197e87.jpg
9fda01d5a01ab9803d08d108078345bf.jpg
From this I can see the file being reprocessed is the correct one. The new file has a new name and appears in the correct directory (the new file can be found there) but the update to the database is not the correct file (this file name relates to an old file that existed before I started working on this feature and has long since been deleted).
I have also tried replacing this code with:
namespace :reprocess_user_photo do
desc "RESIZE"
task :recreate => :environment do
User.all.each do |user|
if user.photo?
puts user.photo_url
user.photo.cache_stored_file!
user.photo.retrieve_from_cache!(user.photo.cache_name)
user.photo.recreate_versions!
puts user.photo_identifier
user.photo = File.basename(user.photo_url)
user.save!
puts user.photo_identifier
end
rescue => e
puts "ERROR: User: #{user.id} -> #{e.to_s}"
end
end
end
which has the output:
/uploads/user/photo/2/0401399fd5c9092d5388e97b1991a295.jpg
0401399fd5c9092d5388e97b1991a295.jpg
0401399fd5c9092d5388e97b1991a295.jpg
This code does not replace the image at all.
Finally I have tried the following:
namespace :reprocess_user_photo do
desc "RESIZE"
task :recreate => :environment do
User.all.each do |user|
if user.photo?
puts user.photo_url
user.photo.cache_stored_file!
user.photo.retrieve_from_cache!(user.photo.cache_name)
user.photo.recreate_versions!
puts user.photo_identifier
user.save!
puts user.photo_identifier
end
rescue => e
puts "ERROR: User: #{user.id} -> #{e.to_s}"
end
end
end
which has the output
/uploads/user/photo/2/946283bd082efbf970784d3c2c00235c.jpg
946283bd082efbf970784d3c2c00235c.jpg
9fda01d5a01ab9803d08d108078345bf.jpg
In this test the new image was created with the file name 5f41bc1e46c67e551e9ea36a8109bae2.jpg
After another day or so of trying to fix my problem I have a solution that kind of works. This is using the following code:
def self.reprocess_user_picture
User.all.each do |user|
if user.photo?
user.photo.recreate_versions!
user.update_column(:photo, File.basename(user.photo.url))
end
end
end
This solution will reprocess all image uploads for the user photo in all versions. It however will not delete the old versions but at least the database is updated correctly.
Now, I know this solution is not perfect. If someone wants to try and answer the original please do and I will try out the solution. The reason why I was struggling with other attempts (and why an old image name was appearing back in the database) is still not clear but I can only think it is some kind of caching that I could not figure out.

The case of the disappearing ActiveRecord attribute

Following the instructions in https://stackoverflow.com/a/24496452/102675 I wound up with the following:
namespace :db do
desc 'Drop, create, migrate, seed and populate sample data'
task seed_sample_data: [:drop, :create, :migrate, :seed, :populate_sample_data] do
puts 'Sample Data Populated. Ready to go!'
end
desc 'Populate the database with sample data'
task populate_sample_data: :environment do
puts Inspector.column_names.include?('how_to_fix')
# create my sample data
end
end
As you would expect, I get true if I run bundle exec rake db:populate_sample_data
BUT if I run bundle exec rake db:seed_sample_data I get all the migration output and then false. In other words I can't see the Inspector attribute how_to_fix even though it definitely exists as proved by the other rake run. Where did my attribute go?
My guess is that this is a "caching" problem. Can you try the following?
task populate_sample_data: :environment do
Inspector.reset_column_information
# ...
end
P.S. We used to have a similar problem working with different databases having the exact same schema (only except some columns here and there)

Create a script or task to modify database

I need to create a script that imports data from a file system source. How do I do that?
I already tried to create a rake task but there the models are not loaded. How do I get the whole rails environment into my task?
desc 'Do stuff with models'
task :do_stuff => :environment do
1000.times.each do |i|
Model.create :name => "model number #{i}"
end
end
You declare :environment as a dependency of your rake task. This loads up rails and all of your app code before it runs.

How can I make Paperclip process files from a server directory?

I want to run Paperclip on all files in a directory on the server. Basically, I would like to allow users to FTP some files to my webserver, then I can manually run a rake task to have Paperclip process all of the files (resize the images, update the database, etc).
How can I do this?
I'm not sure if I understood your question - are you asking to run the rake task remotely or how to import images?
In the later case there is an answer.
First you need some Model to keep the images and maybe some other data, something like this:
class Picture < ActiveRecord::Base
has_attached_file :image, :styles => {
:thumb => "100x100>",
:big => "500x500>"
}
end
You can create simple rake task in your lib/tasks folder (you should name the file with .rake extension)
namespace :import do
desc "import all images from SOURCE_DIR folder"
task :images => :environment do
# get all images from given folder
Dir.glob(File.join(ENV["SOURCE_DIR"], "*")) do |file_path|
# create new model for every picture found and save it to db
open(file_path) do |f|
pict = Picture.new(:name => File.basename(file_path),
:image => f)
# a side affect of saving is that paperclip transformation will
# happen
pict.save!
end
# Move processed image somewhere else or just remove it. It is
# necessary as there is a risk of "double import"
#FileUtils.mv(file_path, "....")
#FileUtils.rm(file_path)
end
end
end
Then you can call manually rake task from the console providing SOURCE_DIR parameter that will be the folder on the server (it can be real folder or mounted remote)
rake import:images SOURCE_DIR=~/my_images/to/be/imported
If you are planning to run this automatically I'd recommend you to go for Resque Scheduler gem.
Update: To keep things simple I've deliberately omitted exception handling

Monkeypatch a model in a rake task to use a method provided by a plugin?

During some recent refactoring we changed how our user avatars are stored not realizing that once deployed it would affect all the existing users. So now I'm trying to write a rake task to fix this by doing something like this.
namespace :fix do
desc "Create associated ImageAttachment using data in the Users photo fields"
task :user_avatars => :environment do
class User
# Paperclip
has_attached_file :photo ... <paperclip stuff, styles etc>
end
User.all.each do |user|
i = ImageAttachment.new
i.photo_url = user.photo.url
user.image_attachments << i
end
end
end
When I try running that though I'm getting undefined method `has_attached_file' for User:Class
I'm able to do this in script/console but it seems like it can't find the paperclip plugin's methods from a rake task.
the rake task is probably not be loading the full Rails environment. You can force it to do so by doing something like this:
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
where the path leads to your environment.rb file. If this were to fix the issue, you should include it inside this task specifically, because you probably do not want all your rake tasks to include the environment by default. In fact, a rake task may not even be the best place to do what you're trying to do. You could try creating a script in the script directory as well.

Resources