我们刚刚从新客户端继承了代码库,并且正在将其引入我们的系统中。
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
文件中的违规行注释掉,但这有点像作弊,并且认为必须有一种更优雅的方法。
谢谢。
答案 0 :(得分:1)
我可以看到2种可能的解决方案:
get '/:locale', to: 'home_pages#index', constraint: -> { |req| Country.where(locale: req.parameters[:locale]).exists? }
注意:您不再需要locale: country_locale
,因为:locale
(在路由声明中)将为您提供此参数,该参数可在请求对象中使用。
约束lambda技巧的作用是-加载应用程序后检查所请求路线的有效性(因此,在加载和评估路线文件时,公司不必位于数据库中)。
缺点是,每当有匹配该路由的请求时,数据库就会受到额外的打击。也许您可以通过一些缓存缓解它。
好处是,您现在可以在运行时添加具有新语言环境的新国家(无需重新启动应用程序),但是我想这不是主要问题。
您可以保留创建路由的方式(遍历所有语言环境并为每个语言定义一个路由),但是可以从文件中加载语言环境。
File.open('locales.txt').each_line do |locale|
get "/#{locale}", to: 'home_pages#index', locale: locale
end
缺点是您需要保持同步(是否出现一些新的国家/消失的情况?)您有时可以将Company.pluck(:locale).join("\n")
转储到此文件中。
我觉得这个特定的rake任务不需要定义路由,但是可能是Rails应用程序环境的加载方式。我遇到了同样的问题(我们在缓存BTW中使用了解决方案1),我想我在某处报告了该问题,但是我找不到它...成功后会共享。
答案 1 :(得分:0)
我的同事发现的一个答案是在运行代码之前通过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