在 Carrierwave 中如何仅在需要时创建版本?上传时不是

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

我设置了一个上传器来将一堆照片上传到相册。然后我让用户以 select 4 张图像作为专辑封面。在他们 select 之后,我需要生成缩小版的照片。只有 selected 4。我该怎么做?

基本上我需要一种在主上传后生成图像版本的方法。我们可以使用类似 refile 的东西。但是问题是,我上传的时候还需要它来创建一些版本!

只需将其放入您的上传器模型中即可:

include CarrierWave::MiniMagick

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

然后在你的视图中,而不是调用 my_model.picture 你可以这样做:

<%= image_tag my_model.picture_url(:thumb) if my_model.picture? %>

建立@karlingen 的回答:

我假设图像记录的 table 上有一个 'selected' 布尔值。

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

在 Carrierwave Uploader 中将您想要向用户显示的版本设置为 select,以及专辑 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.

然后当用户 select 想要使用的相册照片时,您可以在 selected 相册的控制器中调用手动创建版本调用:

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

您也可以考虑将其绑定到 after_update 函数中。

您可以将 Cloudinary 与 carrierwave 一起使用:

安装

安装 Cloudinary 非常简单。首先将它和 Carrier wave 添加到您的 gemfile。

gem 'carrierwave'
gem 'cloudinary'

然后添加 Cloudinary 的安全设置。这些可以在您的 Cloudinary 仪表板上找到。

# config/cloudinary.yml

development:
  cloud_name: "sample"
  api_key: "874837483274837"
  api_secret: "a676b67565c6767a6767d6767f676fe1"

production:
  cloud_name: "sample"
  api_key: "874837483274837"
  api_secret: "a676b67565c6767a6767d6767f676fe1"

现在您可以添加 CarrierWave 上传器了。

rails g uploader avatar

并为新的上传器添加载波。还要注释掉存储和 store_dir 行,因为您使用的不是本地存储,而是 Cloudinary。

app/uploaders/avatar_uploader.rb

class AvatarUploader < CarrierWave::Uploader::Base

  include Cloudinary::CarrierWave

  # Choose what kind of storage to use for this uploader:
  # storage :file
  # storage :fog

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  # def store_dir
  #   "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  # end

end

超级棒!

载波设置

现在我们可以像对待普通 CarrierWave 设置一样对待它。先添加migration,将上传器添加到模型中。

rails g migration add_avatar_to_user avatar:string
rake db:migrate

现在将它添加到我们的模型、表单和视图中。

# app/models/user.rb
attr_accessible :avatar

mount_uploader :avatar, AvatarUploader


# app/views/users/_form.html.erb
<legend>Avatar</legend>
<%= f.file_field :avatar %>


# app/views/users/show.html.erb
<% unless @user.avatar_url.nil? %><%= image_tag @user.avatar_url %><br /><% end %>

太棒了!现在我们真的在滚动。您会注意到 HTML 中的图片来自 res.cloudinary.com 而不是您应用的 URL,这有助于节省带宽。

转换和调整大小

我也去调整了图片的大小。我有两种尺寸,一种用于他们的个人资料,另一种用于当他们出现在用户索引中时。您可以在图像上传器中进行所有转换。 :eager 部分告诉 Cloudinary 在初始图像保存时调整大小,而不是在第一次加载图像时。

# app/uploaders/avatar_uploader.rb

  version :display do
    process :eager => true
    process :resize_to_fill => [200, 200, :north]
  end

  version :thumbnail do
    process :eager => true
    process :resize_to_fit => [50, 50]
  end

然后您可以轻松地从视图中调用调整大小的图像。

<%= image_tag @user.avatar_url(:display) %>

Cloudinary 具有许多其他转换功能,包括 CarrierWave 支持的所有功能和不支持的一些功能。有关更多信息,请查看他们的文档。

享受所有这些图像的乐趣!