This blog post is a quick story of some paths I took to make some of my routes translated. I ended up with a pretty creepy solution for now (still in search for a better one) so bear with me because there is some crappy code in this article.
The thing is that I want the following to work:
http://siteinenglish.com/competition/some_custom_slug
http://siteinenglish.com/competition/some_custom_slug/new
http://siteindutch.nl/competitie/some_custom_slug
http://siteindutch.nl/competitie/some_custom_slug/new
Every site has it's own "top level" model that is named Challenge in my case. On the challenge, an admin can configure the locale that should be used on that site, which in this case can be en and nl.
Gems I tried
I tried the rails-translate-routes and the i18n_routing gems.
The first one didn't work for my Rails 3.0 app.
The second one kind of worked but resolved into some stack level to deep error when trying to apply it to the following resource:
get "competition/:phase_slug" => "phases#show", :as => single_goal_phase
^ Worked!
resources :contributions, :path => "competition/:phase_slug", :as => single_contributions
^ Stack level to deep on some I18n method
Creepy solution with a routing Constraint
The workaround I came up with was to create a route such as:
get ":competition_translation/:phase_slug" => "phases#show", :constraints => TranslationConstraint, :as => single_goal_phase
resources :contributions, :path => ":competition_translation/:phase_slug", :constraints => TranslationConstraint, :as => single_contributions
The TranslationConstraint looking a bit like this (I've simplified a bit to show the example):
class TranslationConstraint
def self.matches?
challenge = Challenge.where({:default_domain => request.host}).first
if challenge && request.params[:competition_translation] == I18n.t('routes.competition')
return true
else
return false
end
end
end
But, since I'm now using a parameter in the route for the resource I also have to override the method that generates the url for the named route and the resource. Like so:
def single_goal_phase_url(options)
options[:competition_translation] = I18n.t('routes.competition')
super(options)
end
Dirty to the bone
All of this feels so super dirty and I have no idea what direction I should go to solve this in a nicer way. My knowledge of the Rails router stops at routes.rb and some advanced Constraining.
Is there anyone out there who's smarter than me?