How to keep the query params when changing locale in Rails 6 - ruby-on-rails

I am trying to preserve query params when changing locale in Rails 6, I only found the default_url_options method & if I try to pass the params to that it doesn't work throwing unpermitted params passed exception
For example:
A URL having http://localhost:3000/some_path?token=ABcasdjlaweQWd
Should be changed to http://localhost:3000/de/some_path?token=ABcasdjlaweQWd
But currently, it only becomes: http://localhost:3000/some_path & I lose the query params
Keeping things secure is important, so I don't want to hack my way disabling the params filter, but it should be possible to pass the params during language change without big hacks.
Update:
I am changing local by navbar link_to btn (for different locale), for example: link_to url_for( :locale => 'fr' ) that will change locale part of the current url to the french locale for example
What is the correct way to maintain the query params on language change?

Without overriding the default_url_options, a better way is to make the language change button behave differently, so that it won't remove the query params
So instead of this:
= link_to url_for( locale: 'en' )
It should be changed to this, which will keep the params:
= link_to request.params.merge( locale: 'en' )

Related

URL helpers with string keys deprecated but params uses them as string by default

I'm updating to rails 4.2 and get this deprecation warning:
Calling URL helpers with string keys controller, action is deprecated. Use symbols instead.
In the controller I am reusing the params to create some links with the same parameters like this:
#csv_prms = params
#csv_prms[:format] = :csv
...
In the view I do:
= link_to 'CSV', report_path(#csv_prms)
Now I noticed that by default the action and controller in params are strings instead of symbols. Isn't that illogical since they are deprecated to use in URL helpers?
In general, you should not pass through params between requests (see params.merge and cross site scripting), but instead slice the params you need for your new request and merge the new ones:
#csv_prms = params.slice(:param1, :param2).merge( format: :csv )
This would remove :controller and :action from the params, which shouldn't be required for creating a link at all, because your link_to statements should consistently link to the action you want (instead of letting the user fumble around with parameters to let your site create links to whatever).

Forward parameters in the specific order (using link_to helper)

I want to forward parameters from one view to the another one, and this is what I managed to do. But I want to pass those parameters in the specific order. On first request, after I send the form, I get the params in the order that I want. For example:
http://www.example.com/someurl?project_id=1&start_date=2016-01-10&end_date=2016-01-20
Then, after I have those params in the view, I generate a link with link_to helper, in this kind of a way:
= link_to "link text", some_specific_path(some_id, {"project_id"=>"1", "start_date"=>"2016-01-10", "end_date"=>"2016-01-20"})
But then, the link will be generated as:
http://www.example.com/someurl?end_date=2016-01-20project_id=1&start_date=2016-01-10
So, the problem is - when I send a form, parameters get added to the url in the order of how they appear in the form. But, when you generate a link with link_to helper and path helper, then parameters are always added in the alphabetical order, no matter how they actually appear.
It is Rails bug https://github.com/rails/rails/issues/1146
also, consider send params between request in sessions.
Ok, my solution for you, but it's realy urly:
hash = {"project_id"=>"1", "start_date"=>"2016-01-10", "end_date"=>"2016-01-20"}
query_string = hash.map{|k,v| "#{k}=#{v}"}.join("&")
link_to "link text", some_specific_path(some_id) + "?" + query_string
It's good idea to define a helper here:
module ApplicationHelper
def link_to_with_sorted_params(text, path, _params)
prepared_params = _params.map { |k,v| "#{k}=#{v}" }.join("&")
prepared_link = "#{path}?#{prepared_params}"
link_to text, prepared_link
end
end
Call it
=link_to_with_sorted_params("hi", users_path, {"user" => 1, "res" => 2})
#=> hi

how to pass '?' character in url (rails)

i want to pass a query to url like
http:/localhost:3000/saldo/;1010917745800000015?1
in my routes i have:
get 'saldo/:nomor' => 'kartus#show_saldo' , as: :show_saldo
and controller:
def show_saldo
#kartu = Kartu.find_by_nomor(params[:nomor])
end
but instead i get this params
Parameters {"1"=> nil,"nomor"=>";1010917745800000015"}
how can i get my param as {"nomor"=>";1010917745800000015?1"}
<%= link_to 'xyz' show_saldo_path(:nomor => 'nomor', :def => 'def'......) %>
In get everything you passed other than url parameter will become your query parameter. def will become your url parameter. More information here.
? is a special character in urls. If you want to include it in the value of a parameter then you should Uri Encode, eg with CGI.escape(), the parameter before submitting it: this will convert "?" to "%3F", and will similarly convert any other special characters (spaces, brackets etc). So, the parameter that is actually submitted will become "%3B1010917745800000015%3F1".
At the server side, rails will call CGI.unescape on the params, so it should show up in your controller as ";1010917745800000015?1" again.
This should happen automatically with form inputs - ie, if someone writes ;1010917745800000015?1 into a text field then it should actually be sent through as "%3B1010917745800000015%3F1"
If you want people to diagnose why this isn't happening then you should include the html (of the form or link which is submitting this value) to your question.

Fast_Gettext Not Displaying Translations in Rails 3.2.13 Application

I have PO files (en.po & fr.po) that I want to use to localize my Rails application into French. I submitted the question https://stackoverflow.com/questions/17203622/translating-a-rails-application-3-2-13-using-po-gettext-files recently to see if I could get any help. I mentioned that I had read some information about Fast-Gettext and another gem. I decided to look at the Fast-Gettext gem since it allows the use of PO files without using a database.
I added the latest versions of fast_gettext and gettext_i18n_rails in my Gemfile. I installed the latter gem to get rid of an undefined method "_" error message even though I have no plans at this point to use the database feature.
I added the following code in config/application.rb.
# add FastGettext configuration
FastGettext.add_text_domain 'my_app', :path => 'config/locales', :type => :po, :ignore_fuzzy => true, :report_warning => false
FastGettext.default_text_domain = 'my_app' # set the default textdomain
FastGettext.default_available_locales = ["en","fr"] # set available locales # (note: the first one is used as a fallback if you try to set an unavailable locale)
FastGettext.default_locale = 'en'
Here is my setup in application_controller.rb to allow the locale to be set and saved using a cookie.
include FastGettext::Translation
before_filter :set_users_locale
def set_users_locale
I18n.locale = FastGettext.set_locale(params[:locale] || cookies[:locale] ||
request.env['HTTP_ACCEPT_LANGUAGE'] || 'en')
cookies[:locale] = I18n.locale if cookies[:locale] != I18n.locale.to_s
end
I added logic where the user can click a flag and set the value of :locale.
<%= link_to_unless_current image_tag("flag_us_30px.jpg", :alt => "Set Language to English"), locale: "en" %>
<%= link_to_unless_current image_tag("flag_fr_30px.jpg", :alt => "Set Language to French"), locale: "fr" %>
When a person clicks the flag it sets the value of :locale correctly. I have my routes formatted as domain.com/:locale/link. Right now the root will include the locale until I add logic to override it.
Here are two statements in my views that I am testing with:
<%= _("Language") %>
<%= _("Note: If you do not understand the text on the icons, use the text links at the bottom of the page.") %>
When I click the French flag to change the value of :locale to "fr" the link changes properly but the code for both strings remains in English. The PO file has the French translation for both of these terms. I would think that if it had not found the PO files that I should be seeing error messages stating it did not find them.
I first attempted to use the configuration code in config/initializers/fast_gettext.rb but did not get any results so I decided to put it in config/application.rb to see if I could get it to work. I also removed ':ignore_fuzzy => true, :report_warning => false' to see if that may change things. However I get the same results.
I am using fast_gettext because back in 2011 #svenfuchs recommended it for using Gettext. I may try and contact him on Twitter since it looks like that is the only place I can find where he is active these days.
Any help would be appreciated.
Why are you using PO files instead of common Rails translations?
Or the globalize3 if you prefer to save the translations on database and add model translations.
There's also a gem to help you converting your existing translations: i18n-translators-tools.

Rails: changing locale and keeping page parameters

I have a navbar with links to different languages:
<%= link_to t('header.english'), locale: "en" %>
The problem is when user tries to switch language on a page which contains additional parameters in the url. Changing locale at this point reloads the page and strips all the additional parameters.
So, how do I pass all the parameters from the current page to the locale switch link?
For example, when
/page/new?param1=1&param2=2
is open, and user switches the locale,
/page/new?locale=en
is opened, and both additional parameters are stripped away from the url.
If you need locale param to stay in all requests it's good to use this approach:
# app/controllers/application_controller.rb
def default_url_options(options={})
{ locale: I18n.locale }
end
from rails guide
EDIT: THIS IS NOT A GOOD WAY TO DO THIS. See comments below.
The problem is that you are not passing the current params to link_to when you create the locale switcher link.
Change your navbar link to:
<%= link_to t('header.english'), params.merge(locale: "en") %>
See also: Add querystring parameters to link_to

Resources