Ruby on rails Rails中基于动态数据库的路由阻止模式:load

Ruby on rails Rails中基于动态数据库的路由阻止模式:load,ruby-on-rails,Ruby On Rails,我们刚刚从一个新客户那里获得了一个代码库,并正在将其引入到我们的系统中 我们发现rake db:schema:load命令有一个小问题,由于routes.rb文件中的以下行,它失败了: if Rails.env.development? || Rails.env.staging? Country.all.each do |country| get "/#{country.locale}", to: 'home_pages#index', locale: country.locale

我们刚刚从一个新客户那里获得了一个代码库,并正在将其引入到我们的系统中

我们发现
rake db:schema:load
命令有一个小问题,由于
routes.rb
文件中的以下行,它失败了:

if Rails.env.development? || Rails.env.staging?
  Country.all.each do |country|
    get "/#{country.locale}", to: 'home_pages#index', locale: country.locale
  end
end
如您所见,这是在检查我们是否处于开发环境中,然后尝试为数据库中的每个国家动态生成路由-但当然,这是失败的,因为数据库中没有国家

经典的陷阱(22;)

我想知道的是,我是否有办法避免这种情况发生?我可以从
routes.rb
文件中暂时注释掉有问题的行,但这感觉有点像作弊,我想一定有一种更优雅的方法可以做到这一点


谢谢。

我可以看到两种可能的解决方案:

1使用约束定义动态管线 注意:您不再需要
locale:country\u locale
,因为
:locale
(在路由声明中)将为您提供请求对象中可用的此参数

约束lambda技巧的作用是——它在加载应用程序后检查请求路由的有效性(因此,在加载和评估路由文件时,公司不必在数据库中)

缺点是每次有与该路由匹配的请求时,都会对数据库造成额外的影响。也许你可以通过一些缓存来缓解它

好处是,现在您可以在运行时添加具有新地区的新国家(无需重新启动应用程序),但我想这不是一个主要问题

2将区域设置转储到文件中,并使其与数据库保持同步 您可以保持创建路由的方式(遍历所有区域设置并为每个区域设置定义一个路由),但从文件中加载区域设置

File.open('locales.txt').each_line do |locale|
  get "/#{locale}", to: 'home_pages#index', locale: locale
end
缺点是您需要保持同步(在某些新国家/地区出现/消失时?),您可以偶尔将
Company.pull(:locale.join(“\n”)
转储到此文件中


我觉得这个特殊的rake任务不需要定义路由,但可能是rails应用程序环境的加载方式。我有同样的问题(我们使用了解决方案1和缓存顺便说一句),我想我报告了它的地方,但我找不到它。。。成功后将与大家分享。

我的同事找到的一个答案是在运行代码之前通过
ActiveRecord::Base.connection
检查数据库表是否存在

现在看起来是这样的:

if (Rails.env.development? || Rails.env.staging? || Rails.env.uat?) && ActiveRecord::Base.connection.table_exists?('countries')
  Country.all.each do |country|
    get "/#{country.locale}", to: 'home_pages#index', locale: country.locale
  end
end

您可以通过写入seed.rb和rake db:seed为国家创建虚拟数据。它可能会解决您的问题:)它不会,
db:seed
也会尝试执行此代码片段。感谢您的回答-在我能够查看您的建议之前,我的一位同事已修复了此问题(张贴在此票据的其他位置),但如果我再次遇到类似问题,我会记住它们。
if (Rails.env.development? || Rails.env.staging? || Rails.env.uat?) && ActiveRecord::Base.connection.table_exists?('countries')
  Country.all.each do |country|
    get "/#{country.locale}", to: 'home_pages#index', locale: country.locale
  end
end