如何在具有 2 个服务器的 rails 应用程序上刷新 ruby 的路由?

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

目标: 我们在 rails 上的 ruby 应用程序根据 table 中的信息动态构建路由,因此当有人编辑信息时table,我们需要一种方法来自动刷新两台服务器上的路由。我们的视图中有一个包含模板的文件夹。根据 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

我们希望在有人更改数据库中模板的短代码时自动更新路线。

我的尝试: 之前,我尝试在 after_save 的模型上添加回调,如果 attribute_changed? 执行 Rails.application.reload_routes!,这就像我们需要的那样刷新路线。但是,因为我们的应用程序有 2 个服务器,它只更新一个服务器上的路由,而不是两个服务器,导致该差异的问题。

真正的问题(最后):在我们的应用程序的两个服务器上刷新路由的最佳方法是什么?我们正在使用 Ruby v2.1.2、Rails v4.1.6 和 mysql.

有多种方法可以实现这一点,但我要做的是简单地向您的 mysql 数据库添加一个触发器来调用一个 API 端点,该端点又会更新路由。

使用 mysql 触发器进行 http 调用的示例:can be found here

为什么不在控制器中只允许所有路由并处理 404?

我会把 config/routes.rb 改成这样:

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

并在 PdfsController 中添加这样的方法:

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

spickermann 说得对(尤其是 XY 问题评论)。我只想提一下你也可以这样做:

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

这给你:

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

'*shortcode' 是通配符匹配器。所以,如果你有一个 URL 像:

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

它将使用 params[:shortcode] == 'a-cool-template' 路由到 templates/pdfs#show

那么,您的 Templates::PdfsController 可能类似于:

class Templates::PdfsController < ApplicationController

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

end

如果app/views/templates/pdfs/a-cool-template.html.erb存在,将被渲染。如果没有,那么您会捕获 MissingTemplate 错误并做出相应的响应。 (顺便说一句,我忘记了 MissingTemplate 错误的实际名称是什么,所以我所拥有的可能不正确。)

如果您有多种模板类型,您可以这样做:

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

这给你:

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