Search code examples
ruby-on-railsruby-on-rails-3internationalizationrails-i18n

I18n clicking navbar link defaults back to English


I'm following the railscast guide but for some reason, when I click on a link, the params locale is not being carried over.

Here's my routes.db

Rails.application.routes.draw do
scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do

get 'welcome/index'

# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".

# You can have the root of your site routed with "root"
root 'welcome#index'

resources :foods
resources :shops
resources :communities
resources :events
resources :pictures
resources :videos
resources :services

end
get '*path', to: redirect("/#{I18n.default_locale}/%{path}")
get '', to: redirect("/#{I18n.default_locale}/")

I think the main difference between my app and the railscasts is I am doing it on the application.html.erb template. So I wonder if that is affecting it.

Thanks for your time!

EDIT:

application controller

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_action :set_locale

private
    def set_locale
      I18n.locale = params[:locale] if params[:locale].present?
end

def default_url_options(options = {})
  {locale: I18n.locale}
end
end

EDIT:

    <li><a href="/foods"><i class="fa fa-cutlery" aria-hidden="true"></i> <%= t('layouts.application.food') %><span class="sr-only">(current)</span></a></li>

Solution

  • The locale scope in your routes file simply ensure that your locale is set depending on the identifier in the url string. However you still have to generate urls containing this identifier in your application, since it is not automatically 'carried over'. To do so, simply set your default url option in application_controller.rb like so:

    def default_url_options(options = {})
      if I18n.default_locale != I18n.locale
        {locale: I18n.locale}.merge options
      else
        {locale: nil}.merge options
      end
    end
    

    Now every time you invoke a route helper such has books_path the current locale will be passed as url parameter just like it would if you had done so explicitly; book_path(locale: I18n.locale).

    This also allows you to get rid of your globbed routes at the bottom of routes.rb since the default locale is set by default in default_url_options. You should also consult this section of the rails guides