如何实现Shrine上传器根据文件类型处理图片与文档上传?
嘿,这个需求很常见,我来帮你调整Shrine的FileUploader类,让它能智能区分图片和文档并分别处理!
首先,我们需要先确保Shrine能准确判断文件类型,然后在处理逻辑里做分支判断。下面是完整的修改代码,我会逐部分解释:
class FileUploader < Shrine plugin :processing plugin :versions plugin :delete_raw plugin :validation_helpers plugin :determine_mime_type # 关键插件:基于文件内容检测MIME类型,比看扩展名靠谱 process(:store) do |io, context| # 判断当前上传的是否为图片文件 if io.mime_type.start_with?('image/') original_file = io.download image_pipeline = ImageProcessing::MiniMagick.source(original_file) # 生成不同尺寸的图片版本(这里示例做800px和400px的缩略图) large_version = image_pipeline.resize_to_limit!(800, 800) medium_version = image_pipeline.resize_to_limit!(400, 400) # 返回包含原文件和缩略图的版本哈希 { original: io, large: large_version, medium: medium_version } else # 非图片文件(PDF/Word/Excel等)直接返回原文件,不需要额外处理 { original: io } end end # 可选:添加文件类型验证,只允许指定类型的文件上传 Attacher.validate do validate_mime_type_inclusion [ # 图片类型 'image/jpeg', 'image/png', 'image/gif', 'image/webp', # 文档类型 'application/pdf', 'application/msword', # .doc 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', # .docx 'application/vnd.ms-excel', # .xls 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' # .xlsx ] end end
关键细节说明:
determine_mime_type插件:这个插件会读取文件内容来判断真实的MIME类型,而不是只看文件扩展名,能有效防止用户通过修改扩展名上传不符合要求的文件。- 图片判断逻辑:用
io.mime_type.start_with?('image/')可以覆盖所有图片类型(比如jpeg、png、webp等),如果你想更严格,也可以直接指定具体的MIME类型数组,比如['image/jpeg', 'image/png'].include?(io.mime_type)。 - 文档处理:非图片文件直接返回原文件即可,不需要额外的图像处理逻辑。
- 类型验证:添加
validate_mime_type_inclusion可以明确限制允许上传的文件类型,提升安全性,避免用户上传恶意文件。
另外,别忘了确保你的Gemfile里已经包含了image_processing和mini_magick这两个gem,因为我们用到了ImageProcessing的MiniMagick处理器来处理图片:
gem 'image_processing' gem 'mini_magick'
这样调整后,你的上传器就能自动识别图片并生成缩略图,文档类文件则直接存储原文件啦!
内容的提问来源于stack exchange,提问作者Aipack
相关产品推荐
相关产品推荐

