我正在使用一个Image
模型来存储有关其他模型(通过多态关联)使用的图像的信息。
我想根据相关模型更改此模型的上载器,以使不同模型具有不同版本。
例如,如果imageable
是Place
,则已挂载的上传器将是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_place
和thumb_user
,因为如果我将它们都命名为thumb
,则只会考虑第一个(即使不满足条件)。 最佳答案
我需要实现相同的逻辑,即我只有一个图像模型,并基于多态关联来安装不同的上传器。
最终我在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