Rails中如何使用Active Storage校验上传图片的尺寸?
Active Storage附件图片尺寸校验实现方案
你找到的activestorage-validator gem本身就内置了完整的尺寸校验能力,不需要额外引入其他工具,针对你要拦截极端比例异常图的需求,有两种可直接落地的方式:
直接使用gem内置的尺寸校验规则
在对应模型的校验逻辑里添加dimension配置即可,除了基础的宽高范围限制,还可以直接配置宽高比阈值,精准拦截异常比例图片,示例代码如下:class Post < ApplicationRecord has_one_attached :cover_image validates :cover_image, blob: { content_type: %w[image/png image/jpg image/jpeg image/webp], size_range: 0.1..10.megabytes, dimension: { # 限制单边像素最小/最大值,拦截过窄/过短的图 width: { min: 50, max: 6000 }, height: { min: 50, max: 6000 }, # 自定义宽高比范围,你提到的3000px*10px的图比例为300,只要把上限设为10、下限设为0.1就能直接拦截 aspect_ratio: { in: 0.1..10 } } } end不依赖gem的自定义校验实现
如果不想引入额外依赖,也可以基于Active Storage自带的附件元数据写自定义校验逻辑,核心是读取附件分析后的宽高元数据,自行判断尺寸和比例,示例代码如下:validate :check_image_dimension_valid private def check_image_dimension_valid return unless cover_image.attached? return unless cover_image.changed? # 仅在附件更新时触发,避免重复IO损耗 # 强制同步分析附件元数据,避免异步分析未完成导致元数据为空 cover_image.analyze unless cover_image.analyzed? width = cover_image.metadata[:width].to_i height = cover_image.metadata[:height].to_i # 拦截单边像素过小的图 if width < 50 || height < 50 errors.add(:cover_image, "图片尺寸过小,无法正常完成裁剪压缩") return end # 拦截极端宽高比的图 ratio = width.to_f / height if ratio < 0.1 || ratio > 10 errors.add(:cover_image, "图片比例异常,不支持上传过长/过窄的图片") end end
注意事项:Active Storage默认会用异步任务分析附件元数据,如果你的业务要求上传时立刻完成校验,要么在校验逻辑里手动调用
analyze方法强制同步读取尺寸,要么在框架配置里关闭异步分析,否则可能出现刚上传的附件元数据为空,导致校验不生效的问题。
内容的提问来源于stack exchange,提问作者isMattCoding
相关产品推荐
相关产品推荐

