Carrierwave的动态上传器

时间:2013-09-19 00:07:35

标签: ruby-on-rails carrierwave

我使用单个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,则只考虑第一个版本(即使它未填写条件)。

1 个答案:

答案 0 :(得分:0)

我需要实现相同的逻辑,我有一个Image模型,并基于多态关联来安装不同的上传者。

最后我在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