Skip to content

Instantly share code, notes, and snippets.

@ryenski
Created January 26, 2018 21:29
Show Gist options
  • Save ryenski/ae987d4177dd1d53a9074ed1da8a53d9 to your computer and use it in GitHub Desktop.
Save ryenski/ae987d4177dd1d53a9074ed1da8a53d9 to your computer and use it in GitHub Desktop.
module Sequential
extend ActiveSupport::Concern
module ClassMethods
def next_custom_id_for_tenant(tenant_id)
raise "Tenant is required" unless tenant_id.present?
# FIXME: Should probably store this value in some external resource, as this could cause race conditions and/or performance issues due to transaction locking.
# Possibly use PG Triggers?
max_id = max_custom_id_for_tenant(tenant_id)
return max_id.to_i + 1
end
def max_custom_id_for_tenant(tenant_id)
unscoped.where(tenant_id: tenant_id).maximum('custom_id')
end
end
included do
validates :tenant, presence: true
before_validation :set_tenant_id, on: :create
before_validation :set_custom_id, on: :create
validates_uniqueness_of :custom_id, scope: :tenant
scope :by_custom_id, -> { order(:custom_id) }
end
def to_param
custom_id.to_s
end
private
def set_custom_id
self.custom_id = self.class.next_custom_id_for_tenant(tenant_id)
end
def set_tenant_id
self.tenant_id ||= Tenant.current_id
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment