Rails链接到当前页面并将parameter passing给它

我通过传递使用url params的语言环境将I18N添加到我的Rails应用程序。 我的url看起来像http://example.com/en/users和http://example.com/ar/users (分别用于英文和阿拉伯语区域)。

在我的路线文件中,我用一个:path_prefix选项定义了我的路线:

map.resources :users, :path_prefix => '/:locale' 

locale使用ApplicationController中定义的before_filter来设置

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

我还定义了ApplicationController#default_url_options,将locale添加到由应用程序生成的所有url:

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

我想要的是添加链接在布局页眉(显示在所有页面),将链接到相同的页面,但与其他语言环境。

例如,如果我正在浏览阿拉伯文语言环境,那么我需要标题中的“英文”链接,这会将我redirect到当前页面,并将语言环境设置为英文。 有没有办法做到这一点在铁轨?

花了我一会儿find这个,但这里是我的解决scheme:

 link_to 'English', url_for( :locale => 'en' ) link_to 'Deutch', url_for( :locale => 'de' ) 

从这里的文档: http : //api.rubyonrails.org/classes/ActionController/Base.html#M000649

在生成新的URL时,可能会从当前请求的参数中填入缺失值。 例如,url_for:action =>'some_action'将按预期保留当前的控制器。 此行为扩展到其他参数,包括:controller,:id以及放置在Routepath中的任何其他参数。

因此,使用url_for将默认为当前请求的参数,只需在代码中更改所需的参数即可。 在这种情况下,所有我改变了:locale,所以一切都保持不变。

注意这也适用于“隐藏”:参数。 所以如果你有:

 map.my_map ':locale/my_map', :controller => 'home', :action => 'my_map' 

在page / en / my_map中使用上面的url_for将不会在url(即/ en / home / my_map)中具有“home”。 奖金。

所以我find了一个更明确地做到这一点的方式,依靠(尽可能多的)铁轨魔术。

 url_for(params.merge({:your_new_parameter => value})) 

这应该在任何link_to工作。

它所做的就是取出当前请求的参数,并将新的期望散列合并到它们中,然后为此创build一个新的URL。

使用不同的语言环境链接到当前页面

testingRails 4

大家好。 经过一段时间的研究,我决定为此编写自己的解决scheme。

 link_to 'English', url_for( :locale => 'en' ) link_to 'Deutch', url_for( :locale => 'de' ) 

这是完美的,但它允许XSS漏洞只是在您的URL中传递参数,如下所示:

 http://localhost:3000/en/about?host=www.fishingsiteorbadurl.com/%23&port=80 

或者最坏的情况:

 http://localhost:3000/en/about?host=%D0%BE%D1%87%D0%B5%D0%BD%D1%8C%D0%BF%D0%BB%D0%BE%D1%85%D0%BE%D0%B9%D1%81%D0%B0%D0%B9%D1%82.%D1%80%D1%84 

看看你的应用程序中通过这个链接后,你会得到什么url。

我的生产解决scheme 方法“更改语言”redirect到任何具有适当语言环境的页面,只需在请求对象中使用HTTP_REFERER即可。 请注意:URI.path方法只获取path,而不是整个url

在任何控制器中进行“改变语言”的方法:

  def change_lang if request.referer.nil? refer = root_url else uri = URI(request.referer) refer = uri.path end lang = params[:lang] cookies[:locale] = lang redirect_to refer end 

application_controller.rb

 before_action :set_locale def set_locale # -- Get lang from cookies or url parameter locale user_locale = cookies[:locale] || params[:locale] # -- If present if user_locale.present? # -- If it is has 2 symbols user_locale = user_locale.scan(/[a-zA-Z]{2}/) else # -- If no - use default en locale user_locale = 'en' end # -- Check, is this locale available for using. # Please note: this needed for disable invalid locale warning. if I18n.available_locales.include?(user_locale[0].to_sym) I18n.locale = user_locale[0] else I18n.locale = "en" end end 

将此添加到您的布局

 <%= link_to 'English', change_lang_path('en') %> <%= link_to 'Russian', change_lang_path('ru') %> 

configuration/ routes.rb中

 scope "(:locale)", locale: /[a-zA-Z]{2}/ do get "change_lang/:lang" => "users#change_lang", :as => "change_lang" end 

没有必要使用params.merge或任何猴子补丁解决scheme。

我希望这有助于,因为我个人花了很多时间来解决它。

您可以parsingrequest_uri,并用正则expression式replacepath中的语言环境

好的,这里是帮手的例子。 如果我正确地理解了目标

 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" 

这是一个起点,所以你可以做一些你需要的东西

看看这个,尽pipe它可能不是干的和适当的,但对我来说是完美的。 它读取您提供的所有参数,只replace语言环境EX URL: 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