Ruby On Rails Updating Heroku Dynamic Routes

2019-03-05 18:08发布

问题:

I've got an app which uses app-wide slugs (uses Slugalicious gem with Sluggable table), and have routed to these slugs by using this code:

  #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

I currently update the routes when I update the slugs model with this code:

after_save :update_routes

def update_routes
    Rails.application.reload_routes!
end

This works perfectly in dev:

The problem I'm getting is that if I update or create a new slug, Heroku doesn't update to accommodate it. It works in development, and (confusingly), it works if I do "heroku run rake routes" on Heroku. But the app just shows a 404 if I try to browse to the new URL. If I redeploy the app, all the routes work, which leads me to believe it's something to do with updating the routes app-wide

This question said it's something to do with running multiple processes on Heroku, but I've yet to find this.

Any ideas? Many thanks in advance

回答1:

Fixed it!

There is something called an "ActiveRecord Observer" which have been depreciated since Rails 4.0. I found this website which explained what I wanted to do, but it was slightly outdated. I've included by code for rails 4.0 below:

If you're using Rails 4, use the rails-observers gem

Add the call to your environment files:

#config/application.rb (can be placed into dev or prod files if required)
config.active_record.observers = :slug_observer

Add a new observer class into your models folder:

#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

The way this works is to call these bolt-on functions once the original has been run. This allowed my app to operate the function indepenent of the model in question, thus updating the routes correctly.