Dynamic database-based routes in Rails preventing schema:load

Multi tool use
Dynamic database-based routes in Rails preventing schema:load
We've just inhered a code base from a new client and are in the process of bringing it across to our systems.
We've got a small problem with the rake db:schema:load
command, in that it's failing due to the following lines in the routes.rb
file:
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
As you can see, this is checking if we're in the development environment, then attempting to dynamically generate routes for each of the countries in the database - but of course, this is failing because there are no countries in the database.
A classic catch 22 ;)
What I was hoping to find out is if there some way I can avoid this from happening? I can temporarily comment out the offending lines from the routes.rb
file, but this feels a bit like cheating, and figured there must be a way of doing this which was a bit more elegant.
routes.rb
Thank you.
It won't,
db:seed
also tries to execute this code fragment.– Marek Lipka
4 hours ago
db:seed
1 Answer
1
I can see 2 possible solutions:
1 define a dynamic route with a constraint
get '/:locale', to: 'home_pages#index', constraint: -> { |req| Country.where(locale: req.parameters[:locale]).exists? }
Note: you don't need locale: country_locale
anymore, because :locale
(in the route declaration) will give you this param available in the request object.
locale: country_locale
:locale
What the constraint lambda trick does is - it checks the validity of the requested route after the app is loaded (so Companies does not have to be in the DB when the routes file is loaded and evaluated).
The downside is the extra hit to the DB each time there's a request matching that route. Maybe you can mitigate it with some caching.
The upside is that you can now add new countries with new locales at runtime (no need to restart the app), but I guess this is not a major concern.
2 dump locales to a file and keep it in sync with the DB
You can keep the way you create routes (iterate through all locales and define one route for each), but load the locales from the file.
File.open('locales.txt').each_line do |locale|
get "/#{locale}", to: 'home_pages#index', locale: locale
end
The downside is that you need to keep that in sync (for the occasion when some new country appears/disappears?) You can occasionally dump Company.pluck(:locale).join("n")
into this file.
Company.pluck(:locale).join("n")
I have a feeling that this particular rake task should not need routes defined, but probably it's the way the rails app environment is loaded. I had the same issue (we used solution 1 with cache BTW) and I think I reported it somewhere but I can't find it... will share when I succeed.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
you can create dummy data for country by writing in seed.rb and rake db:seed . It might solve your problem :)
– Bodharth Lonkar
4 hours ago