Heroku部署Rails应用时Bundler报undefined method `present?`,gem安装失败
问题描述
我在尝试将Rails应用推送到Heroku时遇到了如下异常错误:
remote: -----> Building on the Heroku-20 stack remote: -----> Using buildpack: heroku/ruby remote: -----> Ruby app detected remote: -----> Installing bundler 2.2.16 remote: -----> Removing BUNDLED WITH version in the Gemfile.lock remote: -----> Compiling Ruby/Rails remote: -----> Using Ruby version: ruby-3.0.1 remote: -----> Installing dependencies using bundler 2.2.16 remote: Running: BUNDLE_WITHOUT='development:test' BUNDLE_PATH=vendor/bundle BUNDLE_BIN=vendor/bundle/bin BUNDLE_DEPLOYMENT=1 bundle install -j4 remote: /tmp/build_ae8e646d/bin/bundle:42:in `gemfile': undefined method `present?' for "/tmp/build_ae8e646d/Gemfile":String (NoMethodError) remote: Did you mean? prepend remote: from /tmp/build_ae8e646d/bin/bundle:49:in `lockfile' remote: from /tmp/build_ae8e646d/bin/bundle:57:in `lockfile_version' remote: from /tmp/build_ae8e646d/bin/bundle:68:in `bundler_version' remote: from /tmp/build_ae8e646d/bin/bundle:72:in `bundler_requirement' remote: from /tmp/build_ae8e646d/bin/bundle:100:in `activate_bundler' remote: from /tmp/build_ae8e646d/bin/bundle:88:in `load_bundler!' remote: from /tmp/build_ae8e646d/bin/bundle:116:in `<main>' remote: Bundler Output: /tmp/build_ae8e646d/bin/bundle:42:in `gemfile': undefined method `present?' for "/tmp/build_ae8e646d/Gemfile":String (NoMethodError) remote: Did you mean? prepend remote: from /tmp/build_ae8e646d/bin/bundle:49:in `lockfile' remote: from /tmp/build_ae8e646d/bin/bundle:57:in `lockfile_version' remote: from /tmp/build_ae8e646d/bin/bundle:68:in `bundler_version' remote: from /tmp/build_ae8e646d/bin/bundle:72:in `bundler_requirement' remote: from /tmp/build_ae8e646d/bin/bundle:100:in `activate_bundler' remote: from /tmp/build_ae8e646d/bin/bundle:88:in `load_bundler!' remote: from /tmp/build_ae8e646d/bin/bundle:116:in `<main>' remote: remote: ! remote: ! Failed to install gems via Bundler. remote: ! remote: ! Push rejected, failed to compile Ruby app.
此前我已将该应用的脚手架版本部署到Heroku,运行一切正常。后续开发一段时间再推送变更时就出现了该错误。我已经尝试重新生成Gemfile.lock、执行bundle update操作,均未解决问题。本地运行一切正常,本地使用的Ruby和Bundler版本与Heroku上的版本完全一致。目前暂无排查思路,请问有人遇到过同类错误吗?
解决方案
根因分析
该错误的核心原因是项目下的bin/bundle可执行文件被修改,使用了仅Rails Active Support库提供的present?扩展方法。Heroku在构建阶段执行bundler安装时,还未加载Rails相关依赖,纯Ruby环境没有为字符串类型提供present?方法,因此抛出NoMethodError。
本地运行正常是因为本地执行时已加载Rails运行环境,Active Support的核心扩展已经被注入到字符串类中,不会触发方法不存在的错误。
修复步骤
- 打开项目根目录下的
bin/bundle文件,定位第42行调用present?的代码段 - 将字符串调用
present?的代码替换为纯Ruby原生写法,例如将gemfile_path.present?改为!gemfile_path.nil? && !gemfile_path.empty? - 若不确定如何修改,可直接执行本地命令
rails app:update:bin,选择覆盖bin/bundle文件,恢复为Rails官方默认的binstub内容 - 提交修改后的
bin/bundle文件到代码仓库,重新推送到Heroku即可完成正常构建
内容的提问来源于stack exchange,提问作者Alex Riabukha
相关产品推荐
相关产品推荐

