KorbanDallas
KorbanDallas

Reputation: 11

Rails 5: Search form not preserving locale url parameter

I have a search form on my home page (root_path) that returns the results to the root_path as well. I am making a multilingual site using Ruby I18n and am using the url parameters option, so that the language is specified like so: localhost/?locale=en

For some reason, when submitting the search form, the response is not in the chosen language (it is in the default language), and the locale parameter is now gone from the URL. For example, submitting with localhost/?locale=ja will return with an English page and a URL of localhost/(other search from parameters but no locale)

All other parts of my application preserve the locale parameter correctly (e.g. link_to). Other forms in my application also preserve it correctly when submitted.

There are only two differences I can see between this form and the others.

  1. This form uses method:get
  2. This form is on the root_path

Here is the form:

<%= form_with(url: root_path, local: true, method: :get) do |form|  %>
(various fields)
<%= form.submit t(:submitsearch), name: nil %>

The html that is generated:

<form action="/?locale=en" accept-charset="UTF-8" method="get">

<input type="submit" value="Search" data-disable-with="Search" />

application_controller

class ApplicationController < ActionController::Base
    before_action :set_locale

    def default_url_options
        { locale: I18n.locale }
    end

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

However the url that is requested is:

http://localhost:3000/?utf8=✓&(other parameters - no locale)

Here's an example from my app that behaves as expected

<%= form_with model: @equipment_type, local: true do |form| %>
(various fields)
<%= form.submit %>

which has generated html of

<form action="/equipment_types/2?locale=en" accept-charset="UTF-8" method="post">

<input type="submit" name="commit" value="Update Equipment type" data-disable-with="Update Equipment type" />

I basically need the search form to preserve the user's chosen language, but at the moment it is always reverting to the fallback (and the locale parameter is disappearing from the URL). The form action seems to be getting generated correctly (it has the ?locale=en parameter), but it is not in the request URL or response.

Can anyone suggest what the problem might be here?

Upvotes: 0

Views: 256

Answers (1)

KorbanDallas
KorbanDallas

Reputation: 11

So after a bit more research, the link here suggests that this is default behaviour of browsers and that it is per HTML spec. That is, any query string parameters in the action of a form will be entirely replaced. For rails, that means if you have a form with action GET, even though rails puts the locale parameter in the form action, it will not get used and you will lose the chosen locale (and revert to the default).

As a solution, you can add the following tag to your form:

<%= hidden_field_tag "locale", params[:locale]%>

Which will add the parameter back into the form submission. It's not perfect, because the locale parameter now appears after the UTF8 one (e.g. ?utf8=✓&locale=en) whereas in all other cases, the locale parameter will appear first. Though this is only a minor point.

Upvotes: 1

Related Questions