Skip to content

Commit

Permalink
i18n guide: warn about default_url_options caching and locale selecto…
Browse files Browse the repository at this point in the history
…rs [ci skip]
  • Loading branch information
fxn committed Jun 15, 2015
1 parent c865b82 commit 7789dfe
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions guides/source/i18n.md
Expand Up @@ -216,16 +216,16 @@ We can include something like this in our `ApplicationController` then:

```ruby
# app/controllers/application_controller.rb
def default_url_options(options = {})
{ locale: I18n.locale }.merge options
def default_url_options
{ locale: I18n.locale }
end
```

Every helper method dependent on `url_for` (e.g. helpers for named routes like `root_path` or `root_url`, resource routes like `books_path` or `books_url`, etc.) will now **automatically include the locale in the query string**, like this: `http://localhost:3001/?locale=ja`.

You may be satisfied with this. It does impact the readability of URLs, though, when the locale "hangs" at the end of every URL in your application. Moreover, from the architectural standpoint, locale is usually hierarchically above the other parts of the application domain: and URLs should reflect this.

You probably want URLs to look like this: `www.example.com/en/books` (which loads the English locale) and `www.example.com/nl/books` (which loads the Dutch locale). This is achievable with the "over-riding `default_url_options`" strategy from above: you just have to set up your routes with [`scoping`](http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html) option in this way:
You probably want URLs to look like this: `http://www.example.com/en/books` (which loads the English locale) and `http://www.example.com/nl/books` (which loads the Dutch locale). This is achievable with the "over-riding `default_url_options`" strategy from above: you just have to set up your routes with [`scope`](http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html):

```ruby
# config/routes.rb
Expand All @@ -234,7 +234,9 @@ scope "/:locale" do
end
```

Now, when you call the `books_path` method you should get `"/en/books"` (for the default locale). An URL like `http://localhost:3001/nl/books` should load the Dutch locale, then, and following calls to `books_path` should return `"/nl/books"` (because the locale changed).
Now, when you call the `books_path` method you should get `"/en/books"` (for the default locale). A URL like `http://localhost:3001/nl/books` should load the Dutch locale, then, and following calls to `books_path` should return `"/nl/books"` (because the locale changed).

WARNING. Since the return value of `default_url_options` is cached per request, the URLs in a locale selector cannot be generated invoking helpers in a loop that sets the corresponding `I18n.locale` in each iteration. Instead, leave `I18n.locale` untouched, and pass an explicit `:locale` option to the helper, or edit `request.original_fullpath`.

If you don't want to force the use of a locale in your routes you can use an optional path scope (denoted by the parentheses) like so:

Expand Down

0 comments on commit 7789dfe

Please sign in to comment.