【问题标题】:Dynamic uploader with Carrierwave带有 Carrierwave 的动态上传器
【发布时间】:2013-09-23 22:15:16
【问题描述】:

我正在使用单个 Image 模型来存储有关其他不同模型使用的图像的信息(通过多态关联)。

我想根据关联的模型更改此模型上的上传器,以便为不同的模型提供不同的版本。

例如,如果imageablePlace,则挂载的上传器将是PlaceUploader。如果没有PlaceUploader,则默认为ImageUploader

目前我有:

class Image < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
  mount_uploader :image, ImageUploader
end

理想情况下我想拥有:

# This is not supported by CarrierWave, just a proof of concept
mount_uploader :image, -> { |model| "#{model.imageable.class.to_s}Uploader".constantize || ImageUploader }

有没有办法做到这一点?还是更好的方法来根据关联的模型拥有不同的版本?


编辑

我找到了另一种使用单个 ImageUploader 的解决方案:

class ImageUploader < BaseUploader

  version :thumb_place, if: :attached_to_place? do
    process resize_to_fill: [200, 200]
  end

  version :thumb_user, if: :attached_to_user? do
    process :bnw
    process resize_to_fill: [100, 100]
  end

  def method_missing(method, *args)
    # Define attached_to_#{model}?
    if m = method.to_s.match(/attached_to_(.*)\?/)
      model.imageable_type.underscore.downcase.to_sym == m[1].to_sym
    else
      super
    end
  end

end

如您所见,我的 2 个版本被命名为 thumb_placethumb_user,因为如果我将它们都命名为 thumb,则只会考虑第一个(即使它不满足条件)。

【问题讨论】:

  • 想想你想用单独的上传器实现什么
  • 目标是根据型号有不同的图像版本。实际上我正在使用另一个解决方案(请参阅对原始问题的编辑)。

标签: ruby-on-rails carrierwave


【解决方案1】:

我需要实现相同的逻辑,我有一个单一的图像模型并基于多态关联来挂载不同的上传者。

最后我在 Rails 5 中提出了以下解决方案:

class Image < ApplicationRecord
  belongs_to :imageable, polymorphic: true

  before_save :mount_uploader_base_on_imageable

  def mount_uploader_base_on_imageable
    if imageable.class == ImageableA
      self.class.mount_uploader :file, ImageableAUploader
    else
      self.class.mount_uploader :file, ImageableBUploader
    end
  end
end

【讨论】:

  • 警告:这不是线程安全的,所以如果你想使用需要确保你已将 rails 配置为不使用线程(这会影响你的部署配置文件)。
猜你喜欢
  • 2012-02-19
  • 2015-10-03
  • 1970-01-01
  • 1970-01-01
  • 2018-06-29
  • 2015-06-10
  • 1970-01-01
  • 2014-03-20
  • 1970-01-01
相关资源
最近更新 更多