# Url\_for , to\_param and translate routes

**URL:** <https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454>\
**Category:** Rails I18n\
**Created:** [May 12, 2010, 10:16am UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454 "2010-05-12T10:16:59Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![temesta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e9bcb4/32.png) [@temesta](https://www.ruby-forum.com/u/temesta)\
**Post date:** [May 12, 2010, 10:16am UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454/1 "2010-05-12T10:16:59Z")

</div>

Hello,

Let’s put it simple. The problem is that to\_param generates URLS  
according to the current language.

Suppose my current locale is ‘nl’ and I’m currently viewing an article  
with this URL :

[http://cms/nl/articles/86-wandeling-op-maat-](http://cms/nl/articles/86-wandeling-op-maat-)

On this page I need localized URLS for each language for this page.

so if I generate an URLS like this (using the “translate routes” plugin)  
:

url\_for(params.merge(:locale=\>‘de’))  
url\_for(params.merge(:locale=\>‘en’))

I get this result :

[http://cms/de/articles/86-wandeling-op-maat-](http://cms/de/articles/86-wandeling-op-maat-)  
[http://cms/en/articles/86-wandeling-op-maat-](http://cms/en/articles/86-wandeling-op-maat-)

The links will direct my to the right page, but I can’t figure out how  
to translate the  
to\_params part ! The article id is correct but the last part should also  
be translated  
like this :

[http://cms/de/articles/86-wanderung-nach-mass-](http://cms/de/articles/86-wanderung-nach-mass-)  
[http://cms/en/articles/86-hiking-tour-to-measure-](http://cms/en/articles/86-hiking-tour-to-measure-)

In the article model, my to\_param looks like this:

def to\_param  
“#{id}-#{title($activelanguage.code).downcase.gsub(/[^[:alnum:]]/,‘-’)}”.gsub(/-{2,}/,‘-’)  
end

When the links are generated by url\_for, the $activelanguage (=locale)  
is of course ‘nl’ (=current language) . Is there a way to make url\_for  
pass it’s parameters to to\_param ?

Any help would be appreciated

---

<div class="post-metadata">

**Author:** ![temesta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e9bcb4/32.png) [@temesta](https://www.ruby-forum.com/u/temesta)\
**Post date:** [May 13, 2010, 10:13am UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454/2 "2010-05-13T10:13:38Z")

</div>

Hi,

I18n should know the current locale throughout the request, so there  
should be no need to use a global variable.

You could do this:

def to\_param  
“#{id}-#{title(I18n.locale).downcase.gsub(/[^[:alnum:]]/,‘-’)}”.gsub(/-{2,}/,‘-’)  
end

But passing I18n.locale to the title-method seems a bit odd, since it  
is available there as well.

Hope this helps,

Iain

> **[iain.nl](https://iain.nl/)**
>
> iain's blog

---

<div class="post-metadata">

**Author:** ![temesta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e9bcb4/32.png) [@temesta](https://www.ruby-forum.com/u/temesta)\
**Post date:** [May 17, 2010, 11:02am UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454/3 "2010-05-17T11:02:46Z")

</div>

Iain H. wrote:

> Hi,
> 
> I18n should know the current locale throughout the request, so there  
> should be no need to use a global variable.
> 
> You could do this:
> 
> def to\_param  
> “#{id}-#{title(I18n.locale).downcase.gsub(/[^[:alnum:]]/,‘-’)}”.gsub(/-{2,}/,‘-’)  
> end
> 
> But passing I18n.locale to the title-method seems a bit odd, since it  
> is available there as well.
> 
> Hope this helps,
> 
> Iain  
> [http://iain.nl/](http://iain.nl/)

Hi Lian,

the thing about the global variable isn’t the issue. I’m just storing  
the language record in a variable  
for global use in my CMS. I have e-mail the creator of the translate  
routes plugin, and he suggests  
the following:

You may need to set your  
locale before generating each link:

def i18n\_link\_for(resource, locale)  
current\_i18n = I18n.locale  
I18n.locale = locale  
link = url\_for(…) # now your model should use I18n.locale to set  
the correct text  
I18n.locale = current\_i18n  
link  
end

It’s an improvised and untested code, but I think you can see the point.

I still have to test it

---

<div class="post-metadata">

**Author:** ![temesta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e9bcb4/32.png) [@temesta](https://www.ruby-forum.com/u/temesta)\
**Post date:** [May 17, 2010, 11:42am UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454/4 "2010-05-17T11:42:14Z")

</div>

Hi Maarten,

You should set I18n.locale on every request. This is what my  
application controller usually looks like:

before\_filter :set\_locale  
def set\_locale  
I18n.locale = params[:locale]  
end

I don’t know where your locale comes from. I use the params, but it  
could also come from the session (although that’s not really RESTful).  
This way every request has it’s own locale.

Iain

---

<div class="post-metadata">

**Author:** ![temesta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e9bcb4/32.png) [@temesta](https://www.ruby-forum.com/u/temesta)\
**Post date:** [May 17, 2010, 1:58pm UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454/5 "2010-05-17T13:58:37Z")

</div>

Let’s give some more random advice, hoping that one of these tips is  
the one you need 😉

When I make a link to the same page in another locale I use a hash as  
url parameter:

link\_to “English”, :locale =\> :en  
link\_to “Dutch”, :locale =\> :nl

As for translating multiple times, you can pass the locale option to  
the translate method:

I18n.t(:foo, :locale =\> :jp)

Also, there is no reason as far as I’m aware of that prohibits setting  
I18n.locale multiple times during a request

Hope the right advice is in here 😉

PS. my name is “iain” not “Lian”

---

<div class="post-metadata">

**Author:** ![temesta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e9bcb4/32.png) [@temesta](https://www.ruby-forum.com/u/temesta)\
**Post date:** [May 17, 2010, 12:00pm UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454/6 "2010-05-17T12:00:16Z")

</div>

Iain H. wrote:

> Hi Maarten,
> 
> You should set I18n.locale on every request. This is what my  
> application controller usually looks like:
> 
> before\_filter :set\_locale  
> def set\_locale  
> I18n.locale = params[:locale]  
> end
> 
> I don’t know where your locale comes from. I use the params, but it  
> could also come from the session (although that’s not really RESTful).  
> This way every request has it’s own locale.
> 
> Iain

Lian,

of course the locale is set every request … But it’s not solving the  
problem if you are on page X,  
and need links to the same page, translated in every language. Then you  
have to change the locale  
before generating each link. And then reset the locale back to the  
current locale.

However the suggested solution by Raul (translate routes author) does  
not work ! It seems like you can’t change the locale multiple times per  
request.

---

<div class="post-metadata">

**Author:** ![temesta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e9bcb4/32.png) [@temesta](https://www.ruby-forum.com/u/temesta)\
**Post date:** [May 18, 2010, 10:33am UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454/7 "2010-05-18T10:33:31Z")

</div>

Iain H. wrote:

> Let’s give some more random advice, hoping that one of these tips is  
> the one you need 😉
> 
> When I make a link to the same page in another locale I use a hash as  
> url parameter:
> 
> link\_to “English”, :locale =\> :en  
> link\_to “Dutch”, :locale =\> :nl
> 
> As for translating multiple times, you can pass the locale option to  
> the translate method:
> 
> I18n.t(:foo, :locale =\> :jp)
> 
> Also, there is no reason as far as I’m aware of that prohibits setting  
> I18n.locale multiple times during a request
> 
> Hope the right advice is in here 😉
> 
> PS. my name is “iain” not “Lian”

Hi Iain,

thanks for the advice but I don’t think you understand the problem.  
Passing the locale  
param to link\_to generates indeed urls to translated pages. But  
I18n.locale always remains  
the same in to\_param method of the model. So the article titles are not  
translated in the URL,  
they remain the same. It works but you end up with multiple urls to the  
same page, which is  
bad 🙂

---

<div class="post-metadata">

**Author:** ![temesta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e9bcb4/32.png) [@temesta](https://www.ruby-forum.com/u/temesta)\
**Post date:** [May 24, 2010, 7:39pm UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454/8 "2010-05-24T19:39:17Z")

</div>

Any luck yet in solving this one?

I’v got the same problem and have been googling around but haven’t found  
a solution.

---

<div class="post-metadata">

**Author:** ![temesta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e9bcb4/32.png) [@temesta](https://www.ruby-forum.com/u/temesta)\
**Post date:** [May 26, 2010, 11:45am UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454/9 "2010-05-26T11:45:29Z")

</div>

Hi,

The solution given by the translate\_route plugin author is right. You  
have  
to switch the locale for every generated link.  
But there is still another issue, how do you create your title ? It’s  
from  
an AR object ?  
If it is the case, maybe you should reload your Active Record object  
with  
the current switched locale, as your current object has been loaded with  
your primary locale.

2010/5/24 Lp Lp [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![temesta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e9bcb4/32.png) [@temesta](https://www.ruby-forum.com/u/temesta)\
**Post date:** [May 31, 2010, 11:47am UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454/10 "2010-05-31T11:47:18Z")

</div>

Hi,

The better thing is to reload your objects, you do not have the choice.  
But  
maybe you can just load the name of your record, and not the full object  
?  
After that, use fragment caching for your generated links and this will  
just  
be fine and performant.

2010/5/27 Lp Lp [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![temesta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e9bcb4/32.png) [@temesta](https://www.ruby-forum.com/u/temesta)\
**Post date:** [May 27, 2010, 6:10pm UTC](https://www.ruby-forum.com/t/url-for-to-param-and-translate-routes/188454/11 "2010-05-27T18:10:58Z")

</div>

Guillaume Luccisano wrote:

> Hi,
> 
> The solution given by the translate\_route plugin author is right. You  
> have  
> to switch the locale for every generated link.  
> But there is still another issue, how do you create your title ? It’s  
> from  
> an AR object ?  
> If it is the case, maybe you should reload your Active Record object  
> with  
> the current switched locale, as your current object has been loaded with  
> your primary locale.

Hi and thanks for replying!

The links are generated based on the id and name fields of the loaded  
active record objects.

I did a test and it seems the links do get generated corrently if I  
specify the locale in the object’s to\_param method.

If I reload all of the objects in each page three times (the number of  
translations currently) my site gets a huge performance hit…

I was wondering if it would be possible to generate the ids (id+name  
fields) for each locale in the to\_param method and store them into the  
active record object (as an array for example)? Then this array could be  
utilized by overriding the link\_to method that’s used in the fragments?
