如何动态确定carrierwave uploader列名?

How to dynamically determining carrierwave uploader column name?

我有一些元编程可以将多个直接 S3 上传进程压缩到一个控制器中。然后,这些操作在许多模型之间共享。为了完成这个,除了许多其他细节之外,我需要知道给定模型上传器的列名。我通过在每个使用共享操作的模型中使用 'uploader_name' 方法来促进这一点。例如,我有一个带有收据上传器的费用模型...

def uploader_name
  'receipt'
end 

mount_uploader :receipt, ReceiptUploader

所以,现在我可以调用 Expense.new.uploader_name 到 return 一个字符串,或者在共享操作中我会使用 @obj.send(@obj.uploader_name) 来获取上传者对象(其中@obj 是使用共享操作的任何一个附属模型)。这很好用。但是,我认为我可以清理它。一种可以帮助我重构的方法是不需要 uploader_name 方法。或者,能够在能够动态确定上传者的列名称的共享模块中使用单个 uploader_name 方法。

Carrierwave 中是否有一种方法可以让我在不知道上传器名称的情况下访问模型上传器上的列名称?由于模块在多个 类 之间共享,我必须动态地弄清楚---我已经阅读了载波,但没有找到解决方案。

像这样...例如:

obj = self.class.name
obj.new.uploader # would return the mounted :receipts uploader
obj.new.uploader_column # would return the uploader column, in this case :receipt

上传者提供了一些方法class。所以,为了解决这个问题,我只是将 :mounted_as 方法从上传者委托给调用它的 class 。然后,在不知道实际上传者姓名的情况下,我可以调用 self.mounted_as.to_s 到 return 上传者的姓名。

因此,对于具有头像上传器的用户模型,我这样做了。

class User    
  mount_uploader :avatar, AvatarUploader
  delegate :mounted_as, to: :avatar

所以,如果我调用@user.mounted_as,我会得到 :avatar。或者,更重要的是......如果我调用 self.mounted 当我得到 :avatar 时 self 是一个用户。我有一个在所有使用上传器的模型之间共享的模块。在那个模块中,我包括

def uploader_name
  self.mounted_as.to_s
end

现在,我可以做一些meta-programming,因为我不知道自己是谁,也不知道自己的上传者叫什么。但是,现在我可以动态访问两者。这很有用,因为我可以在多个使用上传器的 class 之间共享一个上传器控制器和一个上传器表单。

我还可以通过简单地在上传者的 extension_whitelist 方法中获取扩展名,将接受的扩展名传递给表单输入(参见 html5 接受选项)。

self.send(uploader_name).extension_whitelist
# this is dynamically getting @user.avatar.extension_whitelist
# or @company.logo.extension_whitelist

我还可以设置上传器属性,例如...

obj.send(obj.uploader_name).content_type = 'image/jpeg'
# this is dynamically setting @user.avatar.content_type = 'image/jpeg'
# or @company.logo.content_type = 'image/jpeg'
obj.class.uploaders.keys.first
=> :receipt