【问题标题】:How come this rails query works locally but fails on Heroku?为什么这个 rails 查询在本地工作但在 Heroku 上失败?
【发布时间】:2013-03-14 21:22:31
【问题描述】:

我的控制器中有以下方法:

@featured_topics = Topic.find_all_by_featured(true)

它在本地运行良好,但是当我将我的网站上传到 Heroku 时,它失败了,并且我收到了 NoMethodError。 “精选”是一个新专栏,但我上传了必要的文件并在 Heroku 上运行了 rake db:migrate。为什么它在 Heroku 上不起作用?该网站的其余部分仍然有效。

【问题讨论】:

  • 您迁移的环境是否正确?
  • @meagar,我刚刚运行了 heroku rake db:migrate,我需要更具体吗?
  • 迁移后是否重启了应用:heroku restart
  • @ThomasKlemm,修复了它,谢谢。它在本地工作而没有任何重启,所以我没有意识到。
  • 听起来迁移未签入或 db:migrate 未成功。运行:heroku run rails console 并检查对象。

标签: ruby-on-rails ruby-on-rails-3 heroku rails-migrations


【解决方案1】:

这里的问题是一个微妙的问题,仅在您的应用处于生产模式时(即当ENV['RAILS_ENV']ENV['RACK_ENV'] = production)出现,这是 Heroku 上的默认配置。

当 Rails 应用程序处于 production 模式时,它不会在每个请求上重新加载类定义(就像在本地运行的 development 模式下一样)。模型类定义的一部分是加载类时从数据库列中获取的属性。因此,如果您在production 中加载一个类,然后更改数据库,加载的类将不知道数据库已更改,您将获得新列的NoMethodError

要了解您在 Heroku 上的情况是如何发生这种情况的,请考虑以下顺序:

  1. 使用新的Topic.find_all_by_featured 列引用部署的应用程序
    1. Heroku 自动重启应用
    2. 一个请求进入您的应用程序,该请求导致类从数据库的当前状态加载到内存中(没有featured 列)
  2. 你跑heroku run bundle exec rake db:migrate
    1. 您在 Heroku 上的数据库已更新为新的 featured
    2. 已经在 Heroku dyno 内存中的模型类没有重新加载。他们仍然不知道新专栏。
  3. 您点击了您的应用程序。 Rails 抛出错误,因为代码中引用的字段不在其数据库列列表中(在第 1 步加载)。

避免这种情况的正确顺序是为部署和数据库迁移打开维护模式:

$ heroku maintenance:on
$ git push heroku master
$ heroku run bundle exec rake db:migrate
$ heroku maintenance:off

在部署和迁移时开启维护可确保您的应用不会处理任何请求,并且不会加载任何类(列列表不正确)。只有在 db 处于正确状态后,您才允许请求。

【讨论】:

    猜你喜欢
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    • 2019-05-12
    • 2021-05-10
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    相关资源
    最近更新 更多