Search code examples
rubyrandom

Create Random Integer Based on Id in Ruby


I have a scenario where I need to generate 4 digit confirmation codes for individual orders. I don't want to just do random codes due to the off chance that two exact codes would be generated near the same time. Is there a way to use the id of each order and generate a 4 digit code from that? I know I am going to eventually have repetitive codes with this but it will be ok because they will not be generated around the same time.


Solution

  • Do you really need to base the code on the ID? Four digits only gives you ten thousand possible values so you could generate them all with a script and toss them in a database table. Then just pull a random one out of the database when you need it and put it back in when you're done with it.

    Your code table would look like this:

    • code: The code
    • uuid: A UUID, a NULL value here indicates that this code is free.

    Then, to grab a code, first generate a UUID, uuid, and do this:

    update code_table
    set uuid = ?
    where code = (
        select code
        from code_table
        where uuid is null
        order by random()
        limit 1
    )
    -- Depending on how your database handles transactions
    -- you might want to add "and uuid is null" to the outer
    -- WHERE clause and loop until it works
    

    (where ? would be your uuid) to reserve the code in a safe manner and then this:

    select code
    from code_table
    where uuid = ?
    

    (where ? is again your uuid) to pull the code out of the database.

    Later on, someone will use the code for something and then you just:

    update code_table
    set uuid = null
    where code = ?
    

    (where code is the code) to release the code back into the pool.

    You only have ten thousand possible codes, that's pretty small for a database even if you are using order by random().

    A nice advantage of this approach is that you can easily see how many codes are free; this lets you automatically check the code pool every day/week/month/... and complain if the number of free codes fall below, say, 20% of the entire code space.

    You have to track the in-use codes anyway if you want to avoid duplicates so why not manage it all in one place?