19

I'm working on a Rails 3.2 application with the following routing conditions:

scope "(:locale)", locale: /de|en/ do
  resources :categories, only: [:index, :show]
  get "newest/index", as: :newest
end

I've a controller with the following:

class LocaleController < ApplicationController
  def set
    session[:locale_override] = params[:locale]
    redirect_to params[:return_to]
  end
end

I'm using this with something like this in the templates:

 = link_to set_locale_path(locale: :de, return_to: current_path(locale: :de)) do
   = image_tag 'de.png', style: 'vertical-align: middle'
     = t('.languages.german')

I'm wondering why there doesn't exist a helper in Rails such as current_path, something which is able to infer what route we are currently using, and re-route to it include new options.

The problem I have is using something like redirect_to :back, one pushes the user back to /en/........ (or /de/...) which makes for a crappy experience.

Until now I was storing the locale in the session, but this won't work for Google, and other indexing services.

I'm sure if I invested enough time I could some up with something that was smart enough to detect which route matched, and swap out the locale part, but I feel like this would be a hack.

I'm open to all thoughts, but this SO question suggests just using sub(); unfortunately with such short and frequently occurring strings as locale short codes, probably isn't too wise.

Community
  • 1
  • 1
Lee Hambley
  • 6,270
  • 5
  • 49
  • 81

2 Answers2

33

If you are using the :locale scope, you can use url_for as current_path:

# Given your page is /en/category/newest with :locale set to 'en' by scope

url_for(:locale => :en) # => /en/category/newest
url_for(:locale => :de) # => /de/kategorie/neueste
iblue
  • 29,609
  • 19
  • 89
  • 128
  • 4
    Nice trick, I ended up writing this: `def current_path(options = {}); options = request.params.symbolize_keys.merge(options); url_for Rails.application.routes.recognize_path(request.path).merge(options) end` which felt overkilled! – Lee Hambley Jun 14 '12 at 16:39
  • 1
    You can also use `url_for` without any arguments. – aef Feb 06 '20 at 08:24
6

In case somebody looks here, you can use request.fullpath which should give you all after domain name and therefore, will include locale.

Kamil Sarna
  • 5,993
  • 1
  • 32
  • 22