Skip to content

Instantly share code, notes, and snippets.

@synth
Last active October 19, 2022 13:51
Show Gist options
  • Save synth/43196a8ccbaf74f510a07019516e93c2 to your computer and use it in GitHub Desktop.
Save synth/43196a8ccbaf74f510a07019516e93c2 to your computer and use it in GitHub Desktop.
Custom Validator for Max Length based on database adapter
module DbMaxLengthValidatorConcern
extend ActiveSupport::Concern
included do
cattr_accessor :column_varchar_max_lengths
self.column_varchar_max_lengths = {}
end
module ClassMethods
def load_schema!
super
setup_column_varchar_max_lengths
end
private
def setup_column_varchar_max_lengths
columns.each do |c|
sql_meta = c.sql_type_metadata
# only handle varchars and text for now
next unless ["varchar", "text"].any?{|type| sql_meta.sql_type.match(type) }
column_varchar_max_lengths[c.name.to_sym] = sql_meta.limit - 1
end
end
end
class DbMaxLengthValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
max_length = record.class.column_varchar_max_lengths[attribute]
return unless value.present? && max_length.present?
unless value.length < max_length
record.errors.add attribute, (options[:message] || _("is too long (maximum is #{max_length} characters)"))
end
end
end
end
# example class that has #sms_body string attribute
class Message < ActiveRecord::Base
include DbMaxLengthValidator
validates :sms_body, db_max_length: true
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment