كل مخترق عمل مع
Ruby On Rails على دراية بـ
ORM ActiveRecord . سنناقش أحد عمليات التحقق المقترحة من خارج الصندوق ، وبالتحديد ، عمليات التحقق من التفرد ، ولماذا ستحفظ جوهرة Database_validations تناسق قاعدة البيانات الخاصة بك.
لنفترض أن لديك نموذج مستخدم فريد في مجال
البريد الإلكتروني ، أي
class User < ApplicationRecord validates :email, uniqueness: true end
قد تعلم بالفعل أن هذا التحقق ينفذ الطلب التالي
SELECT 1 FROM users WHERE email = $1
في كل مرة نحاول فيها حفظ سجل في قاعدة البيانات.
هذا النهج له عيوب عديدة:
أولاً ، تنفيذ طلب إضافي ، وإذا تمت تهيئة العديد من عمليات التحقق من التفرد في النموذج ، فسيتم تنفيذ الطلب لكل منها. هذا ليس فعالًا ، ويتطلب أيضًا فهارسًا إذا أردنا تنفيذ هذه الاستعلامات بسرعة.
ثانيًا ، لا يضمن هذا الحل التفرد بسبب
العرق المحتمل
للبيانات . يمكن أن تتعرف العديد من العمليات التنافسية في وقت واحد عن عدم وجود سجل محدد ، ونتيجة لذلك ، للاحتفاظ بالبيانات نفسها.
بالطبع ، يمكن حل حالات نادرة مع سباق البيانات عن طريق إضافة قيود تفرد على مستوى قاعدة البيانات. ولكن في هذه الحالة ، لن تحصل على خطأ في التحقق من الصحة ، وسوف يسقط الاستعلام إلى قاعدة البيانات ببساطة وسيتم إرجاع المعاملة بالكامل.
في هذه الحالة ، ستساعد gem
database_validations ، مما يوفر التوافق بين قيود قاعدة البيانات وعمليات التحقق.
يتم تقديم المعنى الرئيسي للأحجار الكريمة في الكود التالي:
def save(options = {}) ActiveRecord::Base.connection.transaction(requires_new: true) { super } rescue ActiveRecord::RecordNotUnique => e Helpers.handle_unique_error!(self, e) false end
وبالتالي ، نحاول حفظ البيانات ، إذا تم تمرير جميع عمليات التحقق الأخرى ، إذا سقطت المعاملة وتراجع ، فإننا نقوم بتحليل الخطأ وتعيين القيم الصحيحة
errors
كائننا.
بعد مراجعة
الوثائق والمعايير ، يمكننا أن نستنتج أن هذه الجوهرة ستسرع من عملية حفظ السجلات في قاعدة البيانات مرتين على الأقل.
بفضل دعم قواعد البيانات مثل
PostgreSQL و
SQLite و
MySQL والتوافق مع الإصدارات السابقة مع
validates_uniqueness_of
، تستغرق عملية الاستعاضة عن
validates_db_uniqueness_of
بضع دقائق.
يتوفر أيضًا مُطابق مفيد لـ RSpec خارج منطقة الجزاء:
specify do expect(described_class) .to validate_db_uniqueness_of(:field) .with_message('duplicate') .with_where('(some_field IS NULL)') .scoped_to(:another_field) .with_index(:unique_index) end
عند التبديل إلى عملية تحقق جديدة ، يجب أن يكون لديك قيود على التفرد في قاعدة البيانات ، ولكن إذا لم تكن موجودة بالفعل ، فستشير الأحجار الكريمة إلى هذا عند بدء التطبيق.
تم اختبار الأحجار الكريمة على تطبيق يحتوي على أكثر من 100 عملية تحقق من التفرد بين أكثر من 50 طرازًا.
استخدم الأحجار الكريمة وشارك برأيك. نرحب بأي مساهمة في المزيد من التطوير!