Search code examples
ruby-on-railsrubyruby-on-rails-3devise

Optimise query made by Devise to find user based on remember_token


I am using Devise-1.5.4 with Rails 3.0.20.

Devise provides methods like current_user, authenticate_user! which call authenticate!, which itself calls serialize_from_cookie, that uses remember_token to authenticate the user.

Also, the serialize_from_cookie method receives id as a parameter, so that it queries Users table on the primary key (which is automatically an optimised query).

However, I see queries like select * from users where remember_token = 'XXXXXX' in MySQL logs.

Since the users table has grown huge, these queries are getting slower. I have following questions regarding this:

  1. I am not able to debug where (in code) is Devise making such queries?
  2. How can I optimise these queries (apart from adding indexes)?

Solution

  • Devise does a query to ensure a same token is not already set while setting a new remember_token.

    https://github.com/heartcombo/devise/blob/master/lib/devise/models/rememberable.rb#L146

    # Generate a token checking if one does not already exist in the database.
    def remember_token #:nodoc:
      loop do
        token = Devise.friendly_token
        break token unless to_adapter.find_first({ remember_token: token })
      end
    end