如何在Ruby中查看Heroku数据库版本?MacOS执行命令遇版本错误
我明白你遇到的问题了——在终端里直接跑heroku run rake db:version --remote production完全没问题,但到了Rails控制台里用反引号执行这条命令就炸了,报Ruby版本不匹配的错误。这背后其实是环境变量继承的锅,我来给你拆解一下,再给几个解决方案:
为什么会出错?
当你在Rails控制台里用反引号(或者system、exec)执行shell命令时,这个子shell会继承当前Rails进程的所有环境变量,包括Bundler设置的BUNDLE_GEMFILE等参数。这就导致执行heroku run命令时,本地的Bundler会跳出来检查Ruby版本,但因为控制台进程的环境和你直接在终端里的环境有差异(比如子shell没正确加载RVM的配置),它误判了Ruby版本,抛出了那个1.9版本的错误。
而你直接在终端里执行命令时,你的shell已经正确加载了RVM的Ruby 2.5.1环境和对应的gemset,Bundler能识别到正确的版本,所以一切正常。
解决方案
方案1:绕过Bundler执行命令
在Rails控制台里执行命令时,手动让Bundler不生效,这样就不会触发版本检查了。你可以用system方法加上环境变量覆盖:
system("BUNDLE_GEMFILE=/dev/null heroku run rake db:version --remote production")
这条命令会临时让Bundler找不到Gemfile,从而跳过版本验证,直接执行heroku run命令。
方案2:直接在终端执行(最推荐)
其实你本来就不需要在Rails控制台里做这个操作——heroku run本身就是远程执行命令,和本地Rails控制台的环境完全无关。直接在终端里跑你原来的命令就好,简单又不会出问题:
heroku run rake db:version --remote production
方案3:直接连接生产数据库查询版本
如果想在Rails控制台里获取数据库版本,还有个更直接的方法:直接连接生产数据库查询,不需要通过Heroku的远程命令。不过前提是你能从本地访问生产数据库:
- 先在本地的
config/database.yml里添加生产环境的数据库配置(注意:这个配置不要提交到版本控制,避免泄露敏感信息); - 在Rails控制台里执行以下代码:
# 切换到生产数据库连接 ActiveRecord::Base.establish_connection(:production) # 查询数据库版本(以PostgreSQL为例,MySQL可以用类似的SQL) puts ActiveRecord::Base.connection.select_value("SELECT version();")
如果本地没法直接访问生产数据库,你可以先通过Heroku建立隧道:
heroku pg:psql --remote production -f -
然后再执行上面的控制台代码。
内容的提问来源于stack exchange,提问作者Obromios

