البحث في الموقع
المحتوى عن 'التحقيقات المخصصة'.
-
في الدرسين السابقين ألقينا نظرة عامة حول التحقيقات في Active Record وتعرّفنا على مساعدات التحقيقات وتعرّفنا أيضًا على الخيارات الشائعة وأنواع التحقيقات وسنتابع في هذا الدرس ما تبقى من هذا الدليل التعليمي . 6 أداء/تنفيذ تحقيقات مخصّصة Performing Custom Validations عندما لا تكون التحقيقات المدمجة كافية لاحتياجاتك يمكنك كتابة محققاتك الخاصّة أو وسائل تحقيق كما تفضّل. 6.1 المحققات المخصّصة Custom Validators المحققات المخصصة عبارة عن فئات تقتبس من ActiveModel::Validator. تلك الأصناف يجب أن تنفّذ وسيلة validate التي تأخذ سجل كـتعبير و تُؤدّي التحقيق عليه. يُستدعى المحقق الخاص باستخدام وسيلة validates_with. class MyValidator < ActiveModel::Validator def validate(record) unless record.name.starts_with? 'X' record.errors[:name] << 'Need a name starting with X please!' end end end class Person include ActiveModel::Validations validates_with MyValidator end أسهل طريقة لإضافة محققات مخصّصة للتحقق من خصائص شخصيّة تكون ب ActiveModel::EachValidator مناسب. في هذه الحالة يجب أن ينفّذ المتحقق الخاص وسيلة validate_each ، التي تأخذ ثلاثة تعبيرات: سجل و خاصّية و قيمة. يتم إدارتهم مع ما يناسبهم: الخاصّية يتم التحقق منها ، و قيمة الخاصّية يتم تجاوزها. class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i record.errors[attribute] << (options[:message] || "is not an email") end end end class Person < ApplicationRecord validates :email, presence: true, email: true end كما هو موضّح بالمثال يمكن دمج(ربط) محقّقات أساسيّة بمحقّقاتك الخاصّة. 6.2 الوسائل المخصّصة يمكنك أيضًا إنشاء وسائل تؤكّد على حالة النموذج و تضيف رسائل إلى الـ errorscollection عندما يكونوا غير صالحين. يجب أن تسجّل بعد ذلك تلك الوسائل باستخدام فئة (validate (API ، مرورًا بالرموز الخاصة بأسماء وسائل التحقيق. يمكنك تمرير(إرسال) أكثر من رمز واحد لكل وسيلة لفئة و سيجري التحقيقات المخصصة في نفس الترتيب الذي سُجّلوا به. وسيلة ?valid سوف تؤكّد أن مجموعة الأخطاء فارغة، لذلك يجب أن تضيف تحقيقاتك المخصّصة أخطاء إليها عندما ترغب أن يفشل التحقيق. class Invoice < ApplicationRecord validate :expiration_date_cannot_be_in_the_past, :discount_cannot_be_greater_than_total_value def expiration_date_cannot_be_in_the_past if expiration_date.present? && expiration_date < Date.today errors.add(:expiration_date, "can't be in the past") end end def discount_cannot_be_greater_than_total_value if discount > total_value errors.add(:discount, "can't be greater than total value") end end end كما هي مضبُوطة افتراضيّا ، سوف تعمل هذه التحقيقات كل مرّة تستدعي ?valid أو تحفظ الكائن. لكن من الممكن أيضًا التحكم في وقت عمل هذه التحقيقات بإعطاء خيار on: إلى وسيلة validate إما بـ create: أو update: class Invoice < ApplicationRecord validate :active_customer, on: :create def active_customer errors.add(:customer_id, "is not active") unless customer.active? end end 7 التعامل مع أخطاء التحقيق Working with Validation Errors بالإضافة إلى وسائل ?valid و ?invalid التي تم شرحها مُسبقًا ، يدعم Rails عددًا من الوسائل للتعامل مع مجموعة الأخطاء و يحقق في صحّة الكائن. 7.1 الأخطاء Errors ترجع فئة ActiveModel::Errors يحتوي على كل الأخطاء. كل مفتاح هو اسم الخاصّية و القيمة في مجموعة مصفوفة من المتسلسلات النصّية بالأخطاء. class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end person = Person.new person.valid? # => false person.errors.messages # => {:name=>["can't be blank", "is too short (minimum is 3 characters)"]} person = Person.new(name: "John Doe") person.valid? # => true person.errors.messages # => {} 7.2 الأخطاء [ ] Errors تستخدم errors عندما تريد أن تفحص رسالة الخطأ لخاصّية معيّنة. تقوم بالرد بمجموعة مصفوفة من المتسلسلات النصّية بكل رسائل الأخطاء لخاصّية مُعيّنة ، كل متسلسلة برسالة خطأ واحدة. لو لم يكن هناك أخطاء مرتبطة بالخاصّية ، تقوم بالرد بمصفوفة فارغة. class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end person = Person.new(name: "John Doe") person.valid? # => true person.errors[:name] # => [] person = Person.new(name: "JD") person.valid? # => false person.errors[:name] # => ["is too short (minimum is 3 characters)"] person = Person.new person.valid? # => false person.errors[:name] # => ["can't be blank", "is too short (minimum is 3 characters)"] 7.3 إضافة الأخطاء errors.add تجعلك وسيلة add أن تضيف رسالة خطأ مرتبطة بخاصّية مُعيّنة. تقوم بأخذ الخاصّية و رسالة الخطأ كتعابير. ترد وسيلة errors.full_messages (أو مكافئاتها errors.to_a ) برسالة الخطأ بشكل مفضّل للمستخدم ، و اسم الخاصّية مكبّرًا ومضافًا على بداية كل رسالة ، كما يظهر في الأمثلة بالأسفل. class Person < ApplicationRecord def a_method_used_for_validation_purposes errors.add(:name, "cannot contain the characters !@#%*()_-+=") end end person = Person.create(name: "!@#") person.errors[:name] # => ["cannot contain the characters !@#%*()_-+="] person.errors.full_messages # => ["Name cannot contain the characters !@#%*()_-+="] أن ترفق رسالة في بداية مصفوفة errors.messages لخاصّية ما ، مكافىء لأن تستخدم errors#add . class Person < ApplicationRecord def a_method_used_for_validation_purposes errors.messages[:name] << "cannot contain the characters !@#%*()_-+=" end end person = Person.create(name: "!@#") person.errors[:name] # => ["cannot contain the characters !@#%*()_-+="] person.errors.to_a # => ["Name cannot contain the characters !@#%*()_-+="] 7.4 تفاصيل الأخطاء errors.details يمكنك تحديد نوع محقّق جدول تقطيع تفاصيل الخطأ المُعاد التقطيع باستخدام وسيلة errors.add. class Person < ApplicationRecord def a_method_used_for_validation_purposes errors.add(:name, :invalid_characters) end end person = Person.create(name: "!@#") person.errors.details[:name] # => [{error: :invalid_characters}] لكي تحسّن تفاصيل الأخطاء ، لتحتوي مجموعة الحروف غير المسموح بها على سبيل المثال ، يمكنك تمرير مفاتيح إضافيّة إلى errors.add. class Person < ApplicationRecord def a_method_used_for_validation_purposes errors.add(:name, :invalid_characters, not_allowed: "!@#%*()_-+=") end end person = Person.create(name: "!@#") person.errors.details[:name] # => [{error: :invalid_characters, not_allowed: "!@#%*()_-+="}] كل محقّقات Rails المدمجة تزيد جدول تقطيع التفاصيل بنوع محقّق متناظر. 7.5 قاعدة الأخطاء[ errors [ :base يمكنك إضافة رسائلك أخطاء مرتبطة بحالة الكائن ككل بدلًا من كونها مرتبطة بخاصّية مُعيّنة. يمكنك أيضًا استخدام تلك الوسيلة عندما تريد أن تقول أن الكائن غير صالح للاستخدام ، بغض النظر عن قيم خصائصه. بما أن [errors[ :base مصفوفة ، يمكنك ببساطة إضافة متسلسلة نصّية إليها و سوف تُستَخدَم كَرسالة خطأ. class Person < ApplicationRecord def a_method_used_for_validation_purposes errors[:base] << "This person is invalid because ..." end end 7.6 محو الأخطاء errors.clear تُستخدم وسيلة clear عندما تريد أن تمسح كل رسائل الخطأ في مجموعة الأخطاء errorscollection . بالطبع مناداة errors.clear لكائن غير صالح لن يجعله ساريًا أو صالحًا للاستخدام. مجموعة الأخطاء سوف تُفرّغ ، لكن المرة القادمة التي تستدعي فيها ?valid أو أي وسيلة تحاول أن تحفظ الكائن في قاعدة البيّانات ، سوف تعمل التحقيقات مجّددًا. لو فشل أيّ من التحقيقات سوف تُملأ مجموعة الأخطاء مجددًا. class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end person = Person.new person.valid? # => false person.errors[:name] # => ["can't be blank", "is too short (minimum is 3 characters)"] person.errors.clear person.errors.empty? # => true person.save # => false person.errors[:name] # => ["can't be blank", "is too short (minimum is 3 characters)"] 7.7 حجم الأخطاء errors.size ترد وسيلة size بالعدد الكلي لرسائل الأخطاء للكائن. class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end person = Person.new person.valid? # => false person.errors.size # => 2 person = Person.new(name: "Andrea", email: "andrea@example.com") person.valid? # => true person.errors.size # => 0 8 تقديم أخطاء التحقيق للعرض Displaying Validation Errors in Views بمجرّد إنشائك نموذجًا و إضافة تحقيقات ، لو كان النموذج مصنوع بواسطة شكل المواقع ، من المحتمل أن تريد عرض رسالة عند فشَل أحد التحقيقات. لأن كل تطبيق يعالج هذا النوع من الأشياء بطريقة مختلفة ، لا يتضمّن Rails أي view helpers لتساعدك على توليد تلك الرسائل بصورة مباشرة. مع ذلك ، بسبب فرط الوسائل التي يعطيك إيّاها Rails لكي تتعامل مع التحقيقات بشكل عام، تكون العملية سهلة جدّا لإنشاء ما يخصّك منها. بالاضافة إلى ذلك ، عند إنتاج هيكل رئيسي مساعد ، سوف يضع Rails بعض ERB إلى _form.html.erb الذي تنتجه والذي يعرض قائمة بكل الأخطاء في النموذج. بافتراض أن لدينا نموذج تم حفظه في متغيّر باسم article@ ، سيبدو كالتالي: <% if @article.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h2> <ul> <% @article.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> علاوةً على ذلك، إذا استخدمت تصميم Rails من المساعدين لتولّد تصميماتك(نماذجك)، عندما يحدث خطأ تحقيق في الحقل سوف تنتج <div> إضافي بالقرب من المدخل. <div class="field_with_errors"> <input id="article_title" name="article[title]" size="30" type="text" value=""> </div>` يمكنك حين ذاك تشكيل ال div كما تريد. الهيكل الافتراضى الذي ينتجه Rails على سبيل المثال يضيف قاعدة ال CSS هذِهِ. .field_with_errors { padding: 2px; background-color: red; display: table; } هذا يعني أنّ أي حقل به خطأ ينتهي به الحال بإطار أحمر بعرض 2 بكسل. المصدر: توثيقات Ruby on Rails.