mirror of
https://github.com/ubicloud/ubicloud.git
synced 2025-10-04 05:42:15 +08:00
Previously, links always were displayed as ubids. This changes it to call the admin_label method on the object. By default, this will call name on the object if it is defined, otherwise, it will use the ubid. Use a custom link label of email for Account, since that should be more useful than the account name. This makes many object types automatically have useful link labels. Objects that don't implement name can override admin_label appropriately. Just be careful not to introduce an N+1 query issue when doing so.
165 lines
3.5 KiB
Ruby
165 lines
3.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module ResourceMethods
|
|
def self.configure(model, etc_type: false, redacted_columns: nil, encrypted_columns: nil)
|
|
model.instance_exec do
|
|
extend UbidTypeEtcMethods if etc_type
|
|
@ubid_format = /\A#{ubid_type}[a-z0-9]{24}\z/
|
|
@encrypted_columns = Array(encrypted_columns).freeze
|
|
@redacted_columns = (Array(redacted_columns) + @encrypted_columns).freeze
|
|
|
|
unless @encrypted_columns.empty?
|
|
plugin :column_encryption do |enc|
|
|
@encrypted_columns.each do |col|
|
|
enc.column col
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
module UbidTypeEtcMethods
|
|
def ubid_type
|
|
UBID::TYPE_ETC
|
|
end
|
|
end
|
|
|
|
module InstanceMethods
|
|
def freeze
|
|
ubid
|
|
super
|
|
end
|
|
|
|
def ubid
|
|
@ubid ||= UBID.from_uuidish(id).to_s.downcase
|
|
end
|
|
|
|
def admin_label
|
|
defined?(name) ? name : ubid
|
|
end
|
|
|
|
def to_s
|
|
inspect_prefix
|
|
end
|
|
|
|
def inspect_pk
|
|
ubid if id
|
|
end
|
|
|
|
def before_validation
|
|
set_uuid
|
|
super
|
|
end
|
|
|
|
def set_uuid
|
|
self.id ||= self.class.generate_uuid if new?
|
|
self
|
|
end
|
|
|
|
def validate
|
|
super
|
|
|
|
if self.class.ubid_format.match?(values[:name])
|
|
errors.add(:name, "cannot be exactly 26 numbers/lowercase characters starting with #{self.class.ubid_type} to avoid overlap with id format")
|
|
end
|
|
end
|
|
|
|
INSPECT_CONVERTERS = {
|
|
"uuid" => lambda { |v| UBID.from_uuidish(v).to_s },
|
|
"cidr" => :to_s.to_proc,
|
|
"inet" => :to_s.to_proc,
|
|
"timestamp with time zone" => lambda { |v| v.strftime("%F %T") }
|
|
}.freeze
|
|
def inspect_values_hash
|
|
inspect_values = {}
|
|
sch = db_schema
|
|
@values.except(*self.class.redacted_columns).each do |k, v|
|
|
next if k == :id
|
|
|
|
inspect_values[k] = if v
|
|
if (converter = INSPECT_CONVERTERS[sch[k][:db_type]])
|
|
converter.call(v)
|
|
else
|
|
v
|
|
end
|
|
else
|
|
v
|
|
end
|
|
end
|
|
|
|
inspect_values
|
|
end
|
|
|
|
def inspect_values
|
|
inspect_values_hash.inspect
|
|
end
|
|
|
|
NON_ARCHIVED_MODELS = ["ArchivedRecord", "Semaphore"].freeze
|
|
def before_destroy
|
|
model_name = self.class.name
|
|
unless NON_ARCHIVED_MODELS.include?(model_name)
|
|
model_values = values.merge(model_name:)
|
|
|
|
self.class.encrypted_columns.each do |key|
|
|
model_values.delete(key)
|
|
end
|
|
|
|
ArchivedRecord.create(model_name:, model_values:)
|
|
end
|
|
|
|
super
|
|
end
|
|
end
|
|
|
|
module ClassMethods
|
|
attr_reader :ubid_format
|
|
|
|
attr_reader :encrypted_columns
|
|
|
|
attr_reader :redacted_columns
|
|
|
|
# Adapted from sequel/model/inflections.rb's underscore, to convert
|
|
# class names into symbols
|
|
def self.uppercase_underscore(s)
|
|
s.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').tr("-", "_").upcase
|
|
end
|
|
|
|
def [](arg)
|
|
if arg.is_a?(UBID)
|
|
super(arg.to_uuid)
|
|
elsif arg.is_a?(String) && arg.bytesize == 26
|
|
begin
|
|
ubid = UBID.parse(arg)
|
|
rescue UBIDParseError
|
|
super
|
|
else
|
|
super(ubid.to_uuid)
|
|
end
|
|
else
|
|
super
|
|
end
|
|
end
|
|
|
|
def ubid_type
|
|
UBID.const_get("TYPE_#{ClassMethods.uppercase_underscore(name)}")
|
|
end
|
|
|
|
def generate_ubid
|
|
UBID.generate(ubid_type)
|
|
end
|
|
|
|
def generate_uuid
|
|
generate_ubid.to_uuid
|
|
end
|
|
|
|
def create_with_id(id, **)
|
|
obj = new(**)
|
|
obj.id = id
|
|
obj.save_changes
|
|
end
|
|
|
|
def new_with_id(...)
|
|
new(...).set_uuid
|
|
end
|
|
end
|
|
end
|