我的控制器中有以下方法:
@featured_topics = Topic.find_all_by_featured(true)
它在本地运行良好,但是当我将我的网站上传到 Heroku 时,它失败了,并且我收到了 NoMethodError。“精选”是一个新专栏,但我上传了必要的文件并在 Heroku 上运行了 rake db:migrate。为什么它在 Heroku 上不起作用?该网站的其余部分仍然有效。
我的控制器中有以下方法:
@featured_topics = Topic.find_all_by_featured(true)
它在本地运行良好,但是当我将我的网站上传到 Heroku 时,它失败了,并且我收到了 NoMethodError。“精选”是一个新专栏,但我上传了必要的文件并在 Heroku 上运行了 rake db:migrate。为什么它在 Heroku 上不起作用?该网站的其余部分仍然有效。
这里的问题是一个微妙的问题,仅当您的应用程序处于生产模式(即当ENV['RAILS_ENV']
或ENV['RACK_ENV']
=时production
)时才会出现,这是 Heroku 上的默认配置。
当 Rails 应用程序处于production
模式时,它不会在每个请求上重新加载类定义(就像在development
本地运行的模式下一样)。模型类定义的一部分是加载类时从数据库列中获取的属性。因此,如果您在 中加载一个类production
,然后更改数据库,加载的类将不知道数据库已更改,您将获得NoMethodError
新列的。
要了解您在 Heroku 上的情况如何发生这种情况,请考虑以下顺序:
Topic.find_all_by_featured
使用新列引用
部署的应用程序featured
列)heroku run bundle exec rake db:migrate
featured
列避免这种情况的正确顺序是为部署和数据库迁移打开维护模式:
$ heroku maintenance:on
$ git push heroku master
$ heroku run bundle exec rake db:migrate
$ heroku maintenance:off
在部署和迁移时打开维护可确保您的应用程序不会处理任何请求,并且不会加载任何类(具有不正确的列列表)。只有在数据库处于正确状态后,您才允许请求。