Маршруты Rails с необязательной областью действия ": locale" - PullRequest
12 голосов
/ 22 ноября 2011

Я работаю над приложением Rails 3.1 и хотел бы установить конкретные маршруты для разных языков, которые будет поддерживать приложение.

/es/countries
/de/countries
…

Для языка по умолчанию ('en')Я не хочу, чтобы языковой стандарт отображался в URL.

/countries

Вот определение маршрута, которое я установил.

scope "(:locale)", :locale => /es|de/ do
   resources :countries
end

Он отлично работает, пока я не попробуюиспользовать помощник пути с 'en' в качестве локали.

В консоли:

app.countries_path(:locale => 'fr')
 => "/fr/countries" 

app.countries_path(:locale => 'en')
 => "/countries?locale=en" 

Мне не нужен "? locale = en".

Есть ли способ сообщить рельсам, что в локали 'en' параметр локали не должен добавляться к URL?

Спасибо

Ответы [ 6 ]

21 голосов
/ 12 июля 2014

Это ДОЛЖНО быть лучшим решением:

В вашем rout.rb,

scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/, defaults: {locale: "en"} do

Как сказал MegaTux, установите defaults: {locale: "en"} в области действия.

Преимущество: Решение jlfenaux работает в большинстве случаев, но не во всех.В определенных контекстах (как, например, все, что находится за пределами ваших основных контроллеров и представлений), помощники пути будут сбиты с толку и поместят object или object.id в параметр locale, что приведет к ошибкам.Вы обнаружите, что во многих путевых помощниках вы ставите locale: nil, чтобы избежать этих ошибок.

Возможная проблема: Кажется, что defaults: {locale: "en"} всегда переопределяет любое другое значение, которое вы передаете дляlocale.Опция называется default, поэтому я ожидаю, что она назначит языковой стандарт 'en', только когда значение уже отсутствует, но это не то, что происходит.Кто-нибудь еще испытывает это?

16 голосов
/ 23 ноября 2011

Я наконец понял, как это легко сделать. Вам просто нужно установить default_url_options в контроллере приложения, как показано ниже.

  def default_url_options(options={})
    { :locale => I18n.locale == I18n.default_locale ? nil : I18n.locale  }
  end

Таким образом, вы уверены, что локаль не отправлена ​​помощникам пути.

3 голосов
/ 07 февраля 2016

Я делаю комбинацию того, что делают @Arcolye и @jifenaux, плюс кое-что дополнительное, чтобы сделать код максимально сухим.Возможно, он подходит не для всех, но в моем случае, когда я хочу поддержать новую локаль, мне также необходимо в любом случае создать новый файл .yml в config/locales/, поэтому для меня это лучше всего работает.

config / application.rb:

locale_files = Dir["#{Rails.root}/config/locales/??.yml"]

config.i18n.available_locales = locale_files.map do |d| 
  d.split('/').last.split('.').first
end

config.i18n.default_locale = :en

config / rout.rb

root_path = 'pages#welcome'

scope '(:locale)', locale: /#{I18n.available_locales.join('|')}/ do
  # ...
end

root to: root_path
get '/:locale', to: root_path

app / controllers / application_controller.rb:

private

def default_url_options(options = {})
  if I18n.default_locale != I18n.locale
    {locale: I18n.locale}.merge options
  else
    {locale: nil}.merge options
  end
end
3 голосов
/ 22 ноября 2011

Если вам не нужна строка запроса, вам не нужно передавать ее помощнику:

1.9.2 (main):0 > app.countries_path(:locale=>:de)
=> "/de/countries"
1.9.2 (main):0 > app.countries_path
=> "/countries"
1.9.2 (main):0 > app.countries_path(:locale=>:en)
=> "/countries?locale=en"
1.9.2 (main):0 > app.countries_path
=> "/countries"
1.9.2 (main):0 > app.countries_path(:locale=>nil)
=> "/countries"
0 голосов
/ 08 июля 2019

В моем случае я решил эту проблему, используя эту технику:

class ApplicationController < ActionController::Base
  layout -> {
    if devise_controller?
      'devise'
    end
  }

  before_action :set_locale

  def set_locale
     I18n.locale = params[:locale] || I18n.default_locale
  end

  def url_options
    { :locale => I18n.locale }.merge(super)
  end

end
0 голосов
/ 13 июня 2018

Если вы решите поместить default_url_options в application_controller для исправления ваших помощников пути, имейте в виду, что вы, возможно, захотите добавить его и в application_contoller вашего администратора

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...