97bcdf1853
SQLite columns lengths are purely informational, so we'll enforce the limits via a concern that checks the lengths from the schema.
47 lines
1.3 KiB
Ruby
47 lines
1.3 KiB
Ruby
# Validates string and text column lengths to match MySQL limits.
|
|
# SQLite doesn't enforce column limits, so we need validations to ensure
|
|
# data portability between databases.
|
|
#
|
|
# Usage:
|
|
# class Card < ApplicationRecord
|
|
# include ColumnLimits
|
|
# end
|
|
#
|
|
# This will automatically add length validations for all string and text
|
|
# columns based on their defined limits in the database schema.
|
|
#
|
|
# MySQL VARCHAR limits are in characters, not bytes.
|
|
# MySQL TEXT limits are in bytes.
|
|
|
|
module ColumnLimits
|
|
extend ActiveSupport::Concern
|
|
|
|
included do
|
|
validate :validate_column_limits
|
|
end
|
|
|
|
private
|
|
def validate_column_limits
|
|
self.class.columns.each do |column|
|
|
next unless column.limit
|
|
next unless %i[string text].include?(column.type)
|
|
|
|
value = read_attribute(column.name)
|
|
next if value.nil?
|
|
next unless value.is_a?(String)
|
|
|
|
if column.type == :string
|
|
# VARCHAR limits are in characters
|
|
if value.length > column.limit
|
|
errors.add(column.name, "is too long (maximum is #{column.limit} characters)")
|
|
end
|
|
else
|
|
# TEXT limits are in bytes
|
|
if value.bytesize > column.limit
|
|
errors.add(column.name, "is too long (maximum is #{column.limit} bytes)")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|