Skip to content

Instantly share code, notes, and snippets.

@jbranchaud
Created March 22, 2025 16:55
Show Gist options
  • Save jbranchaud/12813a0558f9cd06bcc24b7d8706550c to your computer and use it in GitHub Desktop.
Save jbranchaud/12813a0558f9cd06bcc24b7d8706550c to your computer and use it in GitHub Desktop.
Idea for a fail-fast Rails initializer to check that database check constraints are in-sync with app code constants
# config/initializers/validate_constraints.rb
Rails.application.config.after_initialize do
if Rails.env.development? || Rails.env.test?
# Get the check constraint from the database schema
connection = ActiveRecord::Base.connection
constraint_sql = nil
# Try to extract the constraint SQL
begin
# For PostgreSQL, you can query the information_schema
result = connection.execute(<<~SQL)
SELECT pg_get_constraintdef(oid) AS def
FROM pg_constraint
WHERE conname = 'reading_statuses_valid_status_check'
AND conrelid = 'reading_statuses'::regclass;
SQL
constraint_sql = result.first["def"] if result.any?
rescue => e
Rails.logger.error("Failed to check constraints: #{e.message}")
end
if constraint_sql
# Extract the values from the constraint SQL
# This is a simplistic approach and may need adjustment based on exact SQL format
db_values = constraint_sql.scan(/'([^']+)'/).flatten.sort
# Get the values from the constants
model_values = ReadingStatusConstants::VALID_STATUSES.sort
# Compare the values
unless db_values == model_values
message = <<~MSG
ERROR: Database constraint and model validation for ReadingStatus.status are out of sync!
Database constraint values: #{db_values.inspect}
Model validation values: #{model_values.inspect}
This can lead to inconsistent behavior where the application accepts values that the database rejects.
Please update the constraint or the model validation to ensure they are in sync.
MSG
Rails.logger.error(message)
raise message if Rails.env.development? # Optional: crash in development
end
else
Rails.logger.warn("Could not find reading_statuses_valid_status_check constraint")
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment