Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Carrierwave how to create a version only when needed? Not when uploading

I have setup an uploader to upload a bunch of photos to an album. Then I let the user to select 4 images for the album cover. After they select it, I need to generate a smaller version of the photos. Only the selected 4. How can I do this?

Basically I need a way to generate image versions after the main upload. We can use something like refile. But the problem is, I also need it to create some versions while uploading!

like image 662
THpubs Avatar asked Apr 08 '15 04:04

THpubs


2 Answers

Building off @karlingen's answer:

I'm going to assume there is a 'selected' boolean value on the table for the image records.

# picture.rb
belongs_to :my_model
scope :chosen, -> { where(selected: true) }

Set the version you want to display to the user to select in the Carrierwave Uploader, along with the versions you want after the album is selected

include CarrierWave::MiniMagick

# Original Version
version :thumb do
  process resize_to_fill: [50, 50]
end

# Processed Later
versions :large_album, if: :is_selected? do
  process resize_to_fill: [500, 500]
end
versions :medium_album, if: :is_selected? do
  process resize_to_fill: [400, 400]
end
versions :small_album, if: :is_selected? do
  process resize_to_fill: [300, 300]
end

private

# Check if it is selected
def is_selected?(picture)
  picture.uploader.model.selected
end

Conditional versions

Occasionally you want to restrict the creation of versions on certain properties within the model or based on the picture itself.

Then when the user selects the album photos they want to use you can call a manual create versions call in the controller on the selected albums:

my_model.pictures.chosen.each do |picture|
    picture.image.recreate_versions!(:large_album, :medium_album, :small_album)
end

Recreating versions

You might come to a situation where you want to retroactively change a version or add a new one. You can use the recreate_versions! method to recreate the versions from the base file. This uses a naive approach which will re-upload and process the specified version or all versions, if none is passed as an argument.

When you are generating random unique filenames you have to call save! on the model after using recreate_versions!. This is necessary because recreate_versions! doesn't save the new filename to the database. Calling save! yourself will prevent that the database and file system are running out of sync..... Or on a mounted uploader

You might also consider tying this into an after_update function.

like image 63
blnc Avatar answered Sep 22 '22 15:09

blnc


Simply drop this into your uploader model:

include CarrierWave::MiniMagick

version :thumb do
  process :resize_to_fill => [50, 50]
end

Then inside your view, instead of calling my_model.picture you can do:

<%= image_tag my_model.picture_url(:thumb) if my_model.picture? %>
like image 42
karlingen Avatar answered Sep 25 '22 15:09

karlingen