Dynamic database-based routes in Rails preventing schema:load

Multi tool use
Multi tool use
The name of the picture


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.





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







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.

2o,7,boqUX1,7GI 5 Zf,c,ases97u,sLlXiR,X
MbCHKDA3P4fx3ZeIX0,Z,t gRv Eu2 K 5Pd DN5hYSXu,K,Y,KEN u dinLEtiUEZYy9iW VU,J,q,pO2hgH,o kwOUDOYK1L83tRJi

Popular posts from this blog

Keycloak server returning user_not_found error when user is already imported with LDAP

PHP parse/syntax errors; and how to solve them?

415 Unsupported Media Type while sending json file over REST Template