Ruby On Rails 更新 Heroku 动态路由

20 浏览
0 Comments

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

这在开发环境中完美运行:

![Routes Work Well In Dev](https://i.stack.imgur.com/arODn.png)

问题是,如果我更新或创建一个新的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上运行多个进程有关,但我还没有找到这个问题的解决方法。

有什么想法吗?非常感谢。

0
0 Comments

问题的出现的原因是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

这种方法的原理是在原始函数运行后调用这些附加函数。这样可以使应用程序独立于相关的模型运行,从而正确更新路由。

0