Rails 6.1 + Ruby 3 环境下Paperclip上传视频渲染报URI escape方法不存在错误
错误原因
- Ruby 3.0+ 正式移除了已经废弃多年的
URI.escape方法 - 你项目中使用的Paperclip版本未适配Ruby 3,在调用
@clip.video生成附件URL时,内部仍在调用已删除的URI.escape接口,因此触发报错。此外Paperclip官方早已停止维护,本身就不支持Ruby 3和Rails 6.1以上版本。
修复方案
方案1:替换为Rails官方Active Storage(推荐)
Active Storage是Rails官方内置的附件管理组件,原生适配Rails 6.1+和Ruby 3,长期维护更稳定:
- 运行命令初始化Active Storage:
rails active_storage:install rails db:migrate
- 修改
clip.rb模型代码,替换Paperclip相关逻辑:
class Clip < ApplicationRecord belongs_to :chapter has_one_attached :video # 视频转码、缩略图生成可以配合active_storage-variant等gem实现 end
- 修改视图代码获取视频URL:
<video autobuffer="autobuffer" autoplay="autoplay" id="hero-video" loop="loop" src="<%= url_for(@clip.video) %>"></video>
方案2:保留Paperclip,打兼容补丁
如果暂时不想重构替换Paperclip,可以用以下两种方式兼容:
方式A:使用社区兼容版Paperclip
修改Gemfile中paperclip的引入:
gem 'paperclip', git: 'https://github.com/thoughtbot/paperclip.git', ref: 'a7320ac7a0af408e6950f20503f20e289b4335a6'
然后执行bundle install即可。
方式B:手动添加URI.escape兼容补丁
在config/initializers/目录下新建paperclip_ruby3_patch.rb,写入以下内容:
# 兼容Ruby 3移除URI.escape的问题 unless URI.respond_to?(:escape) module URI def self.escape(*args) URI::DEFAULT_PARSER.escape(*args) end end end
重启Rails服务即可生效。
额外注意:你的视图代码中直接调用
@clip.video获取URL的写法不正确,Paperclip需要显式调用url方法并指定样式,修改为:<video autobuffer="autobuffer" autoplay="autoplay" id="hero-video" loop="loop" src="<%= @clip.video.url(:medium) %>"></video>其中
:medium对应你定义的转码后样式,需要播放原视频的话改为@clip.video.url即可。
内容的提问来源于stack exchange,提问作者beaconhill
相关产品推荐
相关产品推荐

