module Uuids module Base # Defines custom methods to be defined by `has_uuids` method. module HasUuids extend ActiveSupport::Concern # Model scopes. module ClassMethods # Selects distinct records by uuids (relation scope). # # @example # # class MyRecord < ActiveRecord::Base # include Uuids::Base # has_uuids # end # # MyRecord.by_uuid( # "23423fe3-28d8-a1e5-bde3-2e08074aa92d", # "9223238d-a7e3-2d36-a93d-1e50fea02de2" # ) # # => # # # Params: # *values:: a list of uuids to select records by. # # Returns the ActiveRecord::Relation object. # def by_uuid(*values) first_value = values.first list = first_value.is_a?(Array) ? first_value : values joins(:uuids).where(uuids_uuids: { value: list }).uniq end end # Returns the first UUID (sorted as a string) for the record. # # @example # record.uuids.new value: "23423fe3-28d8-a1e5-bde3-2e08074aa92d" # record.uuids.new value: "9223238d-a7e3-2d36-a93d-1e50fea02de2" # record.uuid # => "23423fe3-28d8-a1e5-bde3-2e08074aa92d" # def uuid uuids.map(&:value).sort.first end # Assigns a new uuid to the record. # # @example # record.uuid = "23423fe3-28d8-a1e5-bde3-2e08074aa92d" # record.uuid # => "23423fe3-28d8-a1e5-bde3-2e08074aa92d" # # Params: # value:: a string value of uuid to assign. # def uuid=(value) uuids.new value: value end # Assigns a list of new uuids to the record. # # @example # record.uuids = [ # "23423fe3-28d8-a1e5-bde3-2e08074aa92d", # "9223238d-a7e3-2d36-a93d-1e50fea02de2" # ] # record.uuids.map(&:value) # # => [ # "23423fe3-28d8-a1e5-bde3-2e08074aa92d", # "9223238d-a7e3-2d36-a93d-1e50fea02de2" # ] # # Params: # values:: an array of uuids string values to assign. # def uuids=(*values) first = values.first list = first.is_a?(Array) ? first : values list.each { |value| self.uuid = value } end private # Creates the uuids by default preventing a record from being ureferrable. def add_default_uuid uuids.present? || uuids.new end # Prevents destruction of a record before its uuids reassigned to # other records. def prevent_destruction return true if uuids.blank? errors.add :base, :uuids_present false end end end end