#23 UUID in Rails with ActiveUUID
3-2-2016

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.
2
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 6 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 6 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