如何在具有 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
目标: 我们在 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