0

I have a private instance user model method like below:-

def generate_authentication_token
  loop do
    token = Devise.friendly_token
    break token unless self.class.unscoped.where(authentication_token:   token).first
  end
end  

Let us assume that, no. of user record is 100 trillions. If I issue the above script and the token generated on each iteration matches with a record then, loop will iterate for 100 trillion times, same will happen with DBMS too for searching record. Is there any solution to make this problem fast, by reducing iteration and reducing db-hits (given that each iteration will give matching record). And seriously, sorry ! if the question makes no sense and let me know, I will delete ASAP. Thanks. Happy Coding.

codemilan
  • 1,072
  • 3
  • 12
  • 32

3 Answers3

1

The code looks fine. find_by(authentication_token: token) is generally preferred for retrieving a single record.

Make sure you add an index for the authentication_token column. That would drastically speed up the query if you have many records. If you don't know about database indexing, see this answer.

I wouldn't worry about optimizing the number of iterations or db hits, as the chances that you will find a matching token even on the first try are slim.

Community
  • 1
  • 1
mlovic
  • 864
  • 6
  • 11
1

Why if you use something like this?

token = Digest::MD5.hexdigest (rand.to_s << Time.now.to_i.to_s)

Here I am creating a random number and appending the Current Time stamp with it and getting MD5 hash for that string value. That will be pretty good secret token and it will be unique.

If you still are not satisfied with the uniqueness criteria then just append the ID of the user at the start.

There is no query involved in it

Qaisar Nadeem
  • 2,404
  • 13
  • 23
  • 1
    This is not guaranteed to be unique. Different input strings can be digested to the same output. – Pascal Jun 03 '16 at 09:54
1

You are looking to create a random yet unique token. Sounds like a UUID to me. You can try https://github.com/assaf/uuid

Your approach will work but will be inefficient for the 100 trillion users you are aiming at:-)

Pascal
  • 8,464
  • 1
  • 20
  • 31