Sunday, May 25, 2014

How to: Override devise default routes for sign in and sign out

In one of my application, I need to override default routes provided by Devise for better SEO.

SEO expert asked me to change default url in such way,
"/users/sign_in" => "/sign-in"
"/users/sign_up" => "/sign-up"

And I know, it is possible in devise. Devise is awesome authentication gem which provides lots of customization as per our app needs. In fact, every gem publisher should study the devise code for better understanding on how to provide api's for customization.

So here is the full customization of default routes,

redirect section : 
        On line 5 and 6, I wrote a redirection rule for SEO purpose and for demonstration over here. But best place is to place redirection rules in your web server, that is in nginx or apache.
        This only applies to you, if your app is already live and search engine has already indexed your sign in and sign out routes.

skip section :
        On line 10, I have skipped generation of default routes for session(sign_in) and registration(sign_up).

devise_scope block :
        In devise_scope block, we need to provide our own urls for sign_in and sign_out. So we need to provide url format with controller and action.
        Also, for each urls, we need to provide path helper using ":as", so that we can still use old path name, without code change.

Tuesday, May 6, 2014

Upgrading from Rails 4.0 to rails 4.1 - My experience

TL;DR: I have recently upgraded one of my rails app from rails version 4.0 to 4.1 and collected steps over here.

Before starting upgrade I went through following link and it is definitely worth to read those links,
1. Rails 4.1 release notes
2. Rails 4.1 upgrade steps

These link almost covered every thing which we need to for rails 4.1 upgrade. Thanks to rails team.

While upgrading you have to note that, your app might be using some gems which is not yet rails-4.1 compatible or might be it's dependent gem.
In my case it was, "sidekiq-failures" which was not compatible with sidekiq-3.0.0 and sidekiq-3.0.0 was rails-4.1 compatible. So I have disabled "sidekiq-failures" for now. ( Author of gem is working on it and might be he has fixed it be the now ).

Here are my steps for rails upgrade.
1. bundle update :
        Bundle update is our routine process, but still I have started with it. So that my stack is ready with all latest gems. You can use "bundle outdated" to check which of your gems are outdated and how much. If major update is happening with any gem then you must have to look into its release notes.

2. Rails 4.1 update and bundle update again :
        Then I have updated rails version first and then bundle update again. Along with this update I have referred rails upgrade steps guide and followed steps which was applicable to my apps.

Out of that important once are,
1. Changes to config/secrets.yml
2. Changes to test helper
3. Addition of spring gem

These are important changes and you have to do it before proceeding.

3. Spec run and code fixes : 
        Running test cases over here is very much important to quickly identify issue with code.
Here are some of failing cases,
a. has_many with through relation :
one of my relation was failing with wrong query
relation was post has_many badges
has_many :badges, -> { order "badgings.id DESC" }, through: :badgings
and failing query is,
"SELECT "badges".* FROM "badges" ORDER BY badgings.id DESC"
So here I was ordering badges using through relation, which is indeed wrong, but I was surprised why it was working previously and not after upgrade. I tried to find cause but not able to find it.
Please comment here, if you know the cause.

For fixing I have changed above line to,
has_many :badges, -> { order "badges.id DESC" }, through: :badgings
b. Complex count quires :
The Major changes, I did with count queries in all pagination. I have changed
@tags.all.count
to
@tags.to_a.count
Please see https://github.com/rails/rails/pull/10710

4. Removed mail_view gem ( If you are using ): 
        Now mail_view gem is part of rails 4.1. As, author of mail_view gem has integrated his gem into rails so there is very less change need to do.
- remove mail_view routes mounting from routes 
- and search and replace MailView to ActionMailer::Preview

Apart from these steps, I have followed following steps which are only applicable if your are using sidekiq-3 or acts-as-taggable-on-3.1
1. For sidekiq :
If you are using Sidekiq for back-grounding and Capistrano for deployment, then your Capistrano script will fail if you have upgraded to Sidekiq-3. Since in Sidekiq-3, Capistrano integrated support has been removed.
To make Capistrano script to work, we need to use "capistrano-sidekiq" gem.
- Just add "capistrano-sidekiq" gem to Gemfile
- And replace "sidekiq/capistrano" to "capistrano/sidekiq" in Capfile.

2. For acts-as-taggable-on :
If you have upgraded acts-as-taggable-on-3.1.1 then you need to run the following generator,
rake acts_as_taggable_on_engine:install:migrations
Since acts-as-taggable-on has added some new columns in tagging system.

And done. Now my app is working on rails 4.1 very smoothly.