我如何使用 Carrierwave DRY-ly 处理多种上传类型?

How do I DRY-ly handle multiple upload types with Carrierwave?

我想让我的用户能够将视频、文档和图像上传到 s3。

我当时在想,与其让每个模型都有一个模型,然后有 3 个不同的上传器 类,不如有 1 个通用上传器并将所有这些文件类型列入白名单。

但我不确定从安全角度来看这是否是最佳方法?

此外,每种类型可能存在细微差异。例如,使用 video 用户应该能够上传视频,或者提供 YouTube link.

最Rails/DRY-way解决这个问题的方法是什么?

您可以创建一个通用类型,然后使用 STI (Single Table Inheritance) 来创建子类型。除非您觉得子类型之间的差异如此之大,以至于某些子类型中会有很多空列,而其他子类型中没有,否则这似乎是最好的方法。从安全的角度来看,我看不出这方面有什么重大影响。

class FileUpload < ActiveRecord::Base
end


class Video < FileUpload
end

class Image < FileUpload
end

class Document < FileUpload
end

然而,不这样做也有合理的理由。通常继承的经验法则是某物是否是一种类型,但在这种情况下存在一些灰色区域。歧义来自于这样一个事实,即文档是一种可上传文件,但它不是一种视频。因此,您希望它具有像视频一样的可上传文件的行为,但这就是相似之处停止的地方。因此,更好的方法可能是创建一个具有所有欲望共享行为的上传功能 module,并将其包含在三个模型中,让它们成为他们的目标。

module Uploadable
end


class Video < ActiveRecord::Base
  include Uploadable
end

class Image < ActiveRecord::Base
  include Uploadable
end

class Document < ActiveRecord::Base
  include Uploadable
end

除了使用 C dot 提到的 STI 之外,您还可以在模型中有一个 jsonb 列,这样就可以在该字段中存储您想要的任何内容。

下面是关于这个主题的好读物: http://nandovieira.com/using-postgresql-and-jsonb-with-ruby-on-rails

t.jsonb :videos, null: false, default: '{}'

user = User.create({
  videos: {
    vimeo: 'https://vimeo.com/123',
    file: 'http://example.com/123.mp4',
    youtube: 'https://youtube.com/watch?v=123'
  }
})

可能是您的问题需要考虑的选项。