Ruby On Rails 更新 Heroku 动态路由
Ruby On Rails 更新 Heroku 动态路由
我有一个使用全局slug的应用程序(使用Slugalicious gem和Sluggable table),并且使用以下代码路由到这些slug:
#Slugs begin Slug.all.each do |s| begin get "#{s.slug}" => "#{s.sluggable_type.downcase.pluralize}#show", :id => s.slug rescue end end rescue end
当我更新slug模型时,我目前使用以下代码更新路由:
after_save :update_routes def update_routes Rails.application.reload_routes! end
这在开发环境中完美运行:

问题是,如果我更新或创建一个新的slug,Heroku不会更新以适应它。它在开发环境中正常工作,并且(令人困惑的是),如果我在Heroku上运行"heroku run rake routes",它也正常工作。但是,如果我尝试浏览新的URL,应用程序只会显示404错误。如果重新部署应用程序,所有路由都会正常工作,这使我相信这与全局更新路由有关。
[这个问题](https://stackoverflow.com/questions/129510/is-it-a-bad-idea-to-reload-routes-dynamically-in-rails)说这与在Heroku上运行多个进程有关,但我还没有找到这个问题的解决方法。
有什么想法吗?非常感谢。
问题的出现的原因是Rails 4.0版本开始,被称为“ActiveRecord Observer”的功能被弃用了。作者在寻找解决方法时,找到了一个稍旧的网站,但方法已经过时了。
解决方法是使用rails-observers gem。首先需要在环境文件中添加以下代码:
# config/application.rb (可以根据需要放置在dev或prod文件中) config.active_record.observers = :slug_observer
然后需要在models文件夹中添加一个新的observer类:
# app/models/slug_observer.rb class SlugObserver < ActiveRecord::Observer def after_save(slug) Rails.application.reload_routes! slug.logger.info("Routes Reloaded") end def after_destroy(slug) Rails.application.reload_routes! slug.logger.info("Routes Reloaded") end end
这种方法的原理是在原始函数运行后调用这些附加函数。这样可以使应用程序独立于相关的模型运行,从而正确更新路由。