简体   繁体   中英

How do I refresh routes for a ruby on rails app that has 2 servers?

The goal: our ruby on rails app dynamically builds routes from information in a table, so when someone edits information in that table, we need a way to refresh the routes on both servers automatically. We have a folder in our views containing templates. A route to that view is automatically created based on data in a table:

routes.rb

namespace :templates do
  templates = PdfTemplate.all.pluck(:shortcode)
  resources :pdfs, only: templates do
    templates.each do |template|
      get template.to_s, on: :collection
    end
  end
end

We want the routes to be updated automatically in the event someone changes the shortcode of a template in the database.

My attempt: Previously, I tried adding a call back on the model for after_save if attribute_changed? to do Rails.application.reload_routes! , which refreshes the routes just like we need. However, because our app has 2 servers, it only updates the routes on one server, not both, causing issues from that discrepancy.

The real question (finally): what's the best way to refresh the routes on both servers of our app? We're using Ruby v2.1.2, Rails v4.1.6, and mysql.

spickermann has it right (especially the XY Problem comment). I just wanted to mention you could also do:

namespace :templates do
  scope :pdfs do 
    get '*shortcode', to: 'pdfs#show', as: :pdf
  end
end

Which gives you:

templates_pdf GET    /templates/pdfs/*shortcode(.:format)   templates/pdfs#show

'*shortcode' is a wildcard matcher. So, if you have a URL like:

localhost:3000/templates/pdfs/a-cool-template

It will route to templates/pdfs#show with a params[:shortcode] == 'a-cool-template' .

Then, your Templates::PdfsController might look something like:

class Templates::PdfsController < ApplicationController

  def show
    begin 
      render params[:shortcode]
    rescue MissingTemplateError
      # do something here
    end
  end

end

If app/views/templates/pdfs/a-cool-template.html.erb exists, it will be rendered. If it doesn't, then you catch the MissingTemplate error and respond accordingly. (BTW, I forget what the actual name of the MissingTemplate error is, so what I have there is probably not correct.)

If you have multiple template types, you could do:

namespace :templates do
  [:pdfs, :html].each do |template_type|
    scope template_type do 
      get '*shortcode', to: "#{template_type}#show", as: template_type
    end
  end
end

Which gives you:

templates_pdfs GET    /templates/pdfs/*shortcode(.:format)  templates/pdfs#show
templates_html GET    /templates/html/*shortcode(.:format)  templates/html#show    

Why do not you just allow all routes and handle 404 in the controller?

I would change the config/routes.rb to something like this:

get 'templates/pdfs/:shortcode', to: 'pfds#routing', via: :get

And add a method like this to the PdfsController :

def routing
  pfd_template = PdfTemplate.find_by!(shortcode: params[:shortcode])
  # code needed to handle the shortcode
end

There are going to be multiple ways to achieve this, but what I would do is simply add a trigger to your mysql database to call an API endpoint which in turn updates the routes.

An example of using mysql triggers to make http calls: can be found here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM