Rails S3上传:如何按Course模型ID为CourseObject文件设置存储路径
实现方法
方法一:使用Paperclip插值(推荐,可复用性更高)
- 第一步:创建/修改Paperclip初始化配置文件
config/initializers/paperclip.rb,添加自定义插值规则,用来获取关联的课程ID:
Paperclip.interpolates :course_id do |attachment, style| # 从当前附件关联的CourseObject实例中取course_id attachment.instance.course_id end
- 第二步:修改CourseObject模型中的
has_attached_file配置,把路径里的(COURSE_ID)替换为我们刚定义的插值变量:course_id,同时新增关联存在校验避免路径异常:
class CourseObject < ActiveRecord::Base belongs_to :course # 新增关联校验,确保course_id不为空 validates :course, presence: true has_attached_file :file,:storage => :s3,:bucket => 'demo-files', # 替换(COURSE_ID)为自定义插值变量:course_id :path => "/capacitation/course_objects/:course_id/content/:filename", :s3_credentials => { :access_key_id => 'key', :secret_access_key => 'secret_key' } validates_attachment_content_type :file, content_type: ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'video/mp4', 'application/pdf', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', :pptx] end
- 第三步:重启Rails服务后配置生效。
方法二:直接用Lambda动态生成路径(无需修改初始化文件)
如果你不想新增初始化配置,也可以直接把path参数设为Lambda动态计算路径:
has_attached_file :file, :storage => :s3, :bucket => 'demo-files', :path => lambda { |attach| "/capacitation/course_objects/#{attach.instance.course_id}/content/:filename" }, :s3_credentials => { :access_key_id => 'key', :secret_access_key => 'secret_key' }
注意事项
- 上传时要确保CourseObject实例的
course_id已经被提前赋值,否则路径会出现空值导致存储路径异常。 - 如果是已经上线的项目,修改路径规则后之前上传的旧文件访问地址会同步变化,需要手动把旧文件迁移到新路径下,否则旧资源会无法访问。
内容的提问来源于stack exchange,提问作者Nicolás
相关产品推荐
相关产品推荐

