Rails : i18n : unexpected redirections

In my app, I have different User types like VehicleOwner , GarageOwner, Admin and unidentified/unauthenticated. I wanted to implement localization for English and Finnish. I was successful, but suddenly all my old URLs stopped working; when I tried to access the old URLs I was redirected to login page, and the login page was also not loading – stuck on infinite redirection loop.

Continue reading

Rails | Devise | Internationalization I18n

If you are upgrading your app from uni-lingual to bilingual, you might want to have separate pages for Devise related pages as well. Its simple for simpler implementation of devise like no ‘omniauth’. But if you are including ‘omniauth’ then normal recommended approach will not work.

# Before
devise_for :users, path: '',
  path_names: { sign_up: :signup, sign_in: :login, sign_out: :logout },
  controllers: {
    registrations:      'devise_override/registrations',
    confirmations:      'devise_override/confirmations',
    sessions:           'devise_override/sessions',
    omniauth_callbacks: 'vehicle_owners/omniauth_callbacks'
  }
# After
devise_for :users, only: :omniauth_callbacks, controllers: {omniauth_callbacks: 'vehicle_owners/omniauth_callbacks'}
scope "(:locale)", locale: /en|fi/ do
  devise_for :users, path: '',
             path_names:   { sign_up: :signup, sign_in: :login, sign_out: :logout },
             controllers:  {
                 registrations:      'devise_override/registrations',
                 confirmations:      'devise_override/confirmations',
                 sessions:           'devise_override/sessions'
             }, skip: :omniauth_callbacks

So, it turns out that you cannot scope the Omniauth related URLs, as it makes no sense. You might also see warnings like

Devise does not support scoping OmniAuth callbacks under a dynamic segment
and you have set "/(:locale)/". You can work around by passing
`skip: :omniauth_callbacks` to the `devise_for` call and extract omniauth
options to another `devise_for` call outside the scope. Here is an example:

 devise_for :users, only: :omniauth_callbacks, controllers: {omniauth_callbacks: 'users/omniauth_callbacks'}

 scope '/(:locale)', locale: /ru|en/ do
   devise_for :users, skip: :omniauth_callbacks
 end

Note: Do not forget to restart the application after any major changes.

Rails : Generate local specific version of current page

If you are about to make your application locale specific then, you must come across with a problem of how you can get locale specific version of the currently hit page; so that your visitor can switch to different language versions of the same page.

There is a helper method called url_for. This method is used by every URLHelper in Rails internally [FYI].

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

For generating a new URL, the missing values may be filled in from the current request‘s parameters. Like, url_for :action => ‘some_action‘ will retain the current controller, as expected. This behavior extends to other parameters, including :controller, :id, and any other parameters that are placed into a Route‘s path.

So, in our case, you are only modifying/setting locale so, the other attributes are default to current request’s attributes.

But, problem with this approach is, I am getting the non-RESTful versions of URL. like

http://localhost:3000/signup?locale=en
# but I am expecting
http://localhost:3000/en/signup

Solution: I did not do anything; formerly the problem was there, but not the problem is gone. May be the application was needing some time to reload the updated code. So, its better to restart the application.