Link do Rails para a página atual e passagem de parâmetros para ela
-
23-09-2019 - |
Pergunta
Estou adicionando I18N ao meu aplicativo Rails, passando o local usando parâmetros de URL.Meus URLs estão parecidos http://example.com/en/users e http://example.com/ar/users (para as localidades inglês e árabe, respectivamente).
No meu arquivo de rotas, defini minhas rotas com uma opção :path_prefix:
map.resources :users, :path_prefix => '/:locale'
E a localidade está sendo definida usando um before_filter definido em ApplicationController
def set_locale
I18n.locale = params[:locale]
end
Também defini ApplicationController#default_url_options, para adicionar localidade a todos os URLs gerados pelo aplicativo:
def default_url_options(options={})
{:locale => I18n.locale}
end
O que eu quero é adicionar um link no cabeçalho do layout (exibido em todas as páginas) que vincularia à mesma página, mas com outra localidade.
Por exemplo, se estou navegando na localidade árabe, quero um link "Inglês" no cabeçalho, que me redirecionará de volta à minha página atual e definirá a localidade como inglês.Existe uma maneira de fazer isso em trilhos?
Solução
Demorei um pouco para encontrar isso, mas aqui está minha solução:
link_to 'English', url_for( :locale => 'en' )
link_to 'Deutch', url_for( :locale => 'de' )
Dos documentos aqui: http://api.rubyonrails.org/classes/ActionController/Base.html#M000649
Ao gerar um novo URL, os valores ausentes podem ser preenchidos a partir dos parâmetros da solicitação atual.Por exemplo, URL_FOR: ACTION => 'Some_Action' reterá o controlador atual, conforme o esperado.Esse comportamento se estende a outros parâmetros, incluindo: controlador,: id e quaisquer outros parâmetros que sejam colocados no caminho de uma rota.
Portanto, usar url_for terá como padrão os parâmetros da solicitação atual, basta alterar o que você deseja em seu código.Neste caso, tudo o que mudei foi :locale, para que todo o resto permaneça igual.
Observe que isso também funciona para parâmetros "ocultos".Então, se você tiver:
map.my_map ':locale/my_map', :controller => 'home', :action => 'my_map'
usar o url_for acima na página /en/my_map não terá 'home' na url (ou seja, /en/home/my_map).Bônus.
Outras dicas
Então, encontrei uma maneira de fazer isso mais explicitamente sem confiar em (tanto) magia do Rails.
url_for(params.merge({:your_new_parameter => value}))
Isso deve funcionar em qualquer link_to
.
Tudo o que está fazendo é pegar os parâmetros da solicitação atual e mesclar o novo hash desejado e, em seguida, criar um novo URL para isso.
Aleatoriamente 3 dias posteriores Alertas de e-mail estão funcionando ... apenas para os usuários que fiz as alterações para:
- Atualizar o objeto de usuário do anúncio para incluir endereço de e-mail
- executar stsadm -o sincronização -synctiming m: 5
- Execute Stsadm -O Sync -Emptiming M: 5.
Você pode analisar solicitações_uri e substituir sua localidade no caminho por expressão regular
Ok, aqui está o exemplo auxiliar. Se eu entender corretamente o objetivo
def locale_url(url, locale)
url.gsub(/\/\w*$/, "/#{locale}")
end
url = "http://www.domain.com/products/1/ru" # or request.request_uri
locale = "en"
locale_url(url, locale) #=> "http://www.domain.com/products/1/en"
Este é um ponto de partida, para que você possa fazer algumas coisas diferentes que você precisa
Dê uma olhada nisso, embora possa não estar seco e adequado, mas funcione perfeitamente para mim. Ele lê todos os parâmetros que você forneceu substituindo apenas os URLs ex Locais: http://example.com:3000/us/users?t=123&m=343 etc.
def us_link
link_to "US", form_locale_url("/us")
end
def jp_link
link_to "Japan",form_locale_url("/jp")
end
def form_locale_url(locale)
new_url = request.request_uri
new_locale_url = new_us_url = new_jp_url = new_url
if new_url == "/"
new_locale_url.sub!(/\//,locale)
elsif (new_url =~/\/us/) == 0
new_us_url.sub!(/\/us/,locale)
elsif (new_url =~/\/jp/) == 0
new_jp_url.sub!(/\/jp/,locale)
end
end
Uma avenida muito mais rápida - e conveniente se você tiver muitos parâmetros que mudam em lugares diferentes ... Evite a desordem com uma tag de âncora que apenas mescla os novos parâmetros de localidade para os existentes (e realmente matando o antigo param do local).
<%= link_to "ру", request.params.merge( locale: 'ru' ) %>