UUID in Rails with ActiveUUID

#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.
0
rails uuid activerecord database 5:11 min

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