Auto default for UUID primary keys
Patch load_schmema! to set the default value for UUID primary keys. This removes the need to patch ApplicationRecord + Rails models individually. It also means we no longer need to patch the default in for the integer primary key in Search::Record::SQLite.
This commit is contained in:
@@ -2,6 +2,4 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
primary_abstract_class
|
||||
|
||||
configure_replica_connections
|
||||
|
||||
attribute :id, :uuid, default: -> { ActiveRecord::Type::Uuid.generate }
|
||||
end
|
||||
|
||||
@@ -2,8 +2,6 @@ module Search::Record::SQLite
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
# Override default UUID id attribute, as FTS5 uses rowid integer primary key
|
||||
attribute :id, :integer, default: nil
|
||||
attribute :result_title, :string
|
||||
attribute :result_content, :string
|
||||
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
# Inject UUID primary key support into Rails framework models
|
||||
# Inject account associations into Rails framework models
|
||||
Rails.application.config.to_prepare do
|
||||
ActionText::RichText.attribute :id, :uuid, default: -> { ActiveRecord::Type::Uuid.generate }
|
||||
ActionText::RichText.belongs_to :account, default: -> { record.account }
|
||||
|
||||
ActiveStorage::Attachment.attribute :id, :uuid, default: -> { ActiveRecord::Type::Uuid.generate }
|
||||
ActiveStorage::Attachment.belongs_to :account, default: -> { record.account }
|
||||
|
||||
ActiveStorage::Blob.attribute :id, :uuid, default: -> { ActiveRecord::Type::Uuid.generate }
|
||||
ActiveStorage::Blob.belongs_to :account, default: -> { Current.account }
|
||||
|
||||
ActiveStorage::VariantRecord.attribute :id, :uuid, default: -> { ActiveRecord::Type::Uuid.generate }
|
||||
ActiveStorage::VariantRecord.belongs_to :account, default: -> { blob.account }
|
||||
end
|
||||
|
||||
@@ -1,4 +1,30 @@
|
||||
# Automatically use UUID type for all binary(16) columns
|
||||
# Automatically use UUID type for all binary(16) columns and generate defaults
|
||||
|
||||
module UuidPrimaryKeyDefault
|
||||
def load_schema!
|
||||
define_uuid_primary_key_pending_default
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
def define_uuid_primary_key_pending_default
|
||||
if uuid_primary_key?
|
||||
pending_attribute_modifications << PendingUuidDefault.new(primary_key)
|
||||
end
|
||||
rescue ActiveRecord::StatementInvalid
|
||||
# Table doesn't exist yet
|
||||
end
|
||||
|
||||
def uuid_primary_key?
|
||||
table_name && primary_key && schema_cache.columns_hash(table_name)[primary_key]&.type == :uuid
|
||||
end
|
||||
|
||||
PendingUuidDefault = Struct.new(:name) do
|
||||
def apply_to(attribute_set)
|
||||
attribute_set[name] = attribute_set[name].with_user_default(-> { ActiveRecord::Type::Uuid.generate })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module MysqlUuidAdapter
|
||||
extend ActiveSupport::Concern
|
||||
@@ -12,6 +38,20 @@ module MysqlUuidAdapter
|
||||
end
|
||||
end
|
||||
|
||||
# Override fetch_type_metadata to preserve UUID type and limit
|
||||
def fetch_type_metadata(sql_type, extra = "")
|
||||
if sql_type == "binary(16)"
|
||||
simple_type = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(
|
||||
sql_type: sql_type,
|
||||
type: :uuid,
|
||||
limit: 16
|
||||
)
|
||||
ActiveRecord::ConnectionAdapters::MySQL::TypeMetadata.new(simple_type, extra: extra)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
class_methods do
|
||||
def native_database_types
|
||||
@native_database_types_with_uuid ||= super.merge(uuid: { name: "binary", limit: 16 })
|
||||
@@ -69,6 +109,7 @@ module TableDefinitionUuidSupport
|
||||
end
|
||||
|
||||
ActiveSupport.on_load(:active_record) do
|
||||
ActiveRecord::Base.singleton_class.prepend(UuidPrimaryKeyDefault)
|
||||
ActiveRecord::ConnectionAdapters::TableDefinition.prepend(TableDefinitionUuidSupport)
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user