#23 UUID in Rails with ActiveUUID

Summary

Some cases require non-auto incrementing primary keys as well as multiple master writes without id conflicts. With ActiveUUID, we can configure our table's primary key with confidence without added complexity.
rails uuid activerecord database 5:11

Summary


Gemfilegem 'activeuuid'


config/initializers/activeuuid.rb   ActiveRecord::Base.connection_pool.with_connection do
      ActiveUUID::Patches.apply!
    end


app/models/concerns/unique_id.rb    module UniqueId
      extend ActiveSupport::Concern

      included do
        include ActiveUUID::UUID
        before_create :populate_uuid

        private

        def populate_uuid
          begin
            self.id = UUIDTools::UUID.random_create
          end while self.class.exists?(id: id)
        end
      end
    end


app/models/entry.rb    class Entry < ActiveRecord::Base
      include UniqueId
      natural_key :lottery_id
      belongs_to :lottery
    end


app/models/lottery.rb    class Lottery < ActiveRecord::Base
      include UniqueId
      has_many :entries, dependent: :destroy
      def winning_entries
        entries.where(numbers: self.winning_number)
      end
    end


database migrations    create_table :entries, id: false  do |t|
      t.uuid :id, primary_key: true
      t.uuid :lottery_id
      ...
      t.timestamps null: false
    end

    create_table :lotteries, id: false  do |t|
      t.uuid :id, primary_key: true
      ...
      t.timestamps null: false
    end

 

db/seeds.rb   def time_rand from = 0.0, to = Time.now
      Time.at(from + rand * (to.to_f - from.to_f))
    end

    10.times do |i|
      puts "Creating Lottery ##{i}"
      lottery = Lottery.new
      lottery.name = "#{Faker::Address.state} #{Faker::Hacker.noun.titleize} Lottery"
      lottery.state = Faker::Address.state_abbr
      winning_number = []
      while winning_number.size < 4
        winning_number << Random.rand(9)
      end
      winning_number = winning_number.join('-')
      lottery.winning_number = winning_number
      random_date = time_rand
      lottery.start_date = random_date
      lottery.end_date = random_date + 1.week
      lottery.save!
      Random.rand(40_000).times do |ii|
        entry = lottery.entries.new
        entry_number = []
        while entry_number.size < 4
          entry_number << Random.rand(9)
        end
        entry_number = entry_number.join('-')
        entry.numbers = entry_number
        puts 'WINNING ENTRY' if winning_number == entry_number
        entry.save!
      end
    end


Kiran Patil said 10 months ago:

Hi,


I want to create a subscriber id which should be unique, can we use UUID as subscriber id ?


In general how people are creating unique subscriber id during registration ?


Do we have any ruby gem to get unique id by providing name, date and other parameter as input to the function to get new unique is ?


I also would like to know the pattern to generate ticket id as well, which is used in incident management where each reported incident is a ticket to be resolved.


Thanks.

kobaltz PRO said 10 months ago:

You could use a UUID for this, but I think that it would probably be a bit overkill.

I would personally just do something like this with SecureRandom.hex (which is part of the ruby core)

        before_create :populate_subscriber_id
        private
        def populate_subscriber_id
          begin
            self.subscriber_id = SecureRandom.hex
          end while self.class.exists?(subscriber_id: subscriber_id)
        end

Login to Comment