📍 Rails без магії: 7 помилок, які роблять навіть мідли
📍 Background jobs: чому “просто Sidekiq” — не завжди просто
📍 Transactions у Rails: чому “і так працює” — небезпечна ілюзія
Майже кожен писав так:
validates :email, uniqueness: true
І здається — все, проблема вирішена.
Але в продакшені раптом з’являються два користувачі з однаковим email.
Чому?
Бо validation — це перевірка на рівні додатку,
а не гарантія на рівні бази.
Ми всі через це проходили 🙂
У чому реальна проблема
Rails validation працює так:
1. Перевіряє — чи існує запис
2. Якщо не існує — створює
Але якщо два запити прийшли одночасно → race condition.
І ти отримуєш дубль.
Що реально захищає
1️⃣ Unique index
add_index :users, :email, unique: true
Ось це вже гарантія.
База не дозволить вставити дубль навіть при конкурентному доступі.
2️⃣ NOT NULL
change_column_null :users, :email, false
Validation можна обійти через
update_column, insert_all
або консоль.
Constraint — ні.
3️⃣ Foreign keys
add_foreign_key :orders, :users
Без foreign key можна легко отримати “висячі” записи.
4️⃣ Check constraints (просунутий рівень)
Наприклад, статус лише з дозволеного списку:
add_check_constraint :orders, "status IN ('new', 'paid', 'cancelled')"
Тепер БД сама не дозволить некоректні дані.
Маленьке правило
Validation — це зручність.
Constraint — це гарантія.
Якщо дані критичні — вони мають бути захищені на рівні БД.
Типова помилка
Розробник каже:
“У нас же є validation.”
Але продакшен — це завжди про конкурентність, баги і непередбачувані сценарії.
І база — остання лінія оборони.
У кого був кейс, коли validation “пройшла”, а база зламалась? І що тоді довелося чистити вручну? 😄
TikTok | Instagram | Telegram