الفرق بين المراجعتين لصفحة: «Rails/active record basics»

من موسوعة حسوب
ط تعديل التصنيفات
طلا ملخص تعديل
سطر 2: سطر 2:
[[تصنيف:Rails]]
[[تصنيف:Rails]]
[[تصنيف:Rails Models]]
[[تصنيف:Rails Models]]
هذا الدليل هو مدخل إلى السجل الفعَّال (Active Record). بعد قراءة هذا الدليل، ستتعرف على:
هذا الدليل هو مدخل إلى المكتبة Active Record. بعد قراءة هذا الدليل، ستتعرف على:
* ما هي تقنية ORM (اختصار للعبارة Object Relational Mapping أي "ربط الكائنات العِلاقيَّة") والسجل الفعَّال وكيفية استعمالهما في ريلز.
* ما هي تقنية ORM (اختصار للعبارة Object Relational Mapping أي "ربط الكائنات العِلاقيَّة") والسجل الفعَّال وكيفية استعمالهما في ريلز.
* كيف ينسجم السجل الفعَّال مع النموذج MVC (اختصار للعبارة Model-View-Controller).
* كيف ينسجم السجل الفعَّال مع النموذج MVC (اختصار للعبارة Model-View-Controller).
سطر 9: سطر 9:
* مفهوم تهجيرات، وتحققات، وردود نداء قاعدة البيانات.
* مفهوم تهجيرات، وتحققات، وردود نداء قاعدة البيانات.


== ما هو السجل الفعال؟ ==
== ما هو Active Record؟ ==
إن السجل الفعال هو الحرف M في [[wikipedia:Model–view–controller|MVC]] - أي "النموذج" (Model)، الذي يعبر عن الطبقة المسؤولة عن تمثيل منطق العمل وبياناته في النظام. يسهّل السجل الفعال عمليّة إنشاء واستخدام الكائنات التي يجب المحافظة على بياناتها في قاعدة بيانات. السجل الفعال هو تنفيذ "لنمط السجل الفعال" (Active Record Pattern)، والذي يعبر بذاته عن نظام ربط الكائنات بالعلاقات (Object Relational Mapping).
إن Active Record هو الحرف M في [[wikipedia:Model–view–controller|MVC]] - أي "النموذج" (Model)، الذي يعبر عن الطبقة المسؤولة عن تمثيل منطق العمل وبياناته في النظام. يسهّل Active Record عمليّة إنشاء واستخدام الكائنات التي يجب المحافظة على بياناتها في قاعدة بيانات. Active Record هو تنفيذ "[[wikipedia:Active_record_pattern|لنمط Active Record]]"، والذي يعبر بذاته عن نظام ربط الكائنات بالعلاقات (Object Relational Mapping).


=== نمط السجل الفعال ===
=== نمط Active Record ===
شُرح [http://www.martinfowler.com/eaaCatalog/activeRecord.html نمط عمل السجل الفعال] من قبل مارتن فولر (Martin Fowler) في كتابه "أنماط معمارية التطبيقات المؤسساتية" (Patterns of Enterprise Application Architecture). في السجل الفعال، تحمل الكائنات البيانات المحفوظة والسلوك المنفذ على هذه البيانات. يأخذ السجل الفعال بالحسبان الرأي الذي ينص على أن ضمان الوصول للبيانات عبر جزء من الكائن سيجعل المستخدمين على دراية بهذا الكائن وكيفية قراءة وكتابة البيانات من وعلى قاعدة البيانات.
شُرح [http://www.martinfowler.com/eaaCatalog/activeRecord.html نمط عمل Active Record] من قبل مارتن فولر (Martin Fowler) في كتابه "أنماط معمارية التطبيقات المؤسساتية" (Patterns of Enterprise Application Architecture). في Active Record، تحمل الكائنات البيانات المحفوظة والسلوك المنفذ على هذه البيانات. يأخذ Active Record بالحسبان الرأي الذي ينص على أن ضمان الوصول للبيانات عبر جزء من الكائن سيجعل المستخدمين على دراية بهذا الكائن وكيفية قراءة وكتابة البيانات من وعلى قاعدة البيانات.


=== ربط الكائنات بالعلاقات ===
=== ربط الكائنات بالعلاقات ===
سطر 20: سطر 20:
'''ملاحظة''': إذا لم تكن ملمًا بأنظمة إدارة قواعد البيانات العلائقية، أو بلغة الاستعلام البنيوية [[SQL]]، يرجى الاطلاع على توثيق لغة SQL أو الاطلاع [https://academy.hsoub.com/programming/sql/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%B9%D9%86-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r584/ هذا] المقال (و[https://academy.hsoub.com/programming/sql/ المقالات الأخرى حول SQL] في [https://academy.hsoub.com أكاديمية حسوب]). إن فهم طريقة عمل قواعد البيانات العلائقية مهم جدًا لفهم السجلات الفعالة في ريلز بشكل عام.
'''ملاحظة''': إذا لم تكن ملمًا بأنظمة إدارة قواعد البيانات العلائقية، أو بلغة الاستعلام البنيوية [[SQL]]، يرجى الاطلاع على توثيق لغة SQL أو الاطلاع [https://academy.hsoub.com/programming/sql/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%B9%D9%86-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r584/ هذا] المقال (و[https://academy.hsoub.com/programming/sql/ المقالات الأخرى حول SQL] في [https://academy.hsoub.com أكاديمية حسوب]). إن فهم طريقة عمل قواعد البيانات العلائقية مهم جدًا لفهم السجلات الفعالة في ريلز بشكل عام.


=== السجل الفعال كإطار عمل ORM ===
=== Active Record كإطار عمل ORM ===
يزوّد السجل الفعال بمجموعة من المهام، أهمها القابلية على:
يزوّد Active Record بمجموعة من المهام، أهمها القابلية على:
* تمثيل النماذج (models) وبياناتها.
* تمثيل النماذج (models) وبياناتها.
* تمثيل العلاقات بين هذه النماذج.
* تمثيل العلاقات بين هذه النماذج.
سطر 28: سطر 28:
* تنفيذ عمليات قواعد البيانات بشكل غرضي التوجه.
* تنفيذ عمليات قواعد البيانات بشكل غرضي التوجه.


== العرف مقابل الضبط في السجل الفعال ==
== العرف فوق الضبط في Active Record ==
عند كتابة التطبيقات باستخدام لغات برمجة أو واجهات عمل أخرى، قد يكون من الضروري كتابة الكثير من تعليمات التهيئة والضبط الضرورية لعمل التطبيق. يعد ذلك صحيحًا من أجل واجهات عمل ORM بشكل عام. لكن إذا اتبعت العرف المتبنى من قبل ريلز، فستحتاج إلى كتابة القليل من تعليمات التهيئة (وبعض الأوقات قد لا تحتاج إلى كتابة تهيئة مطلقًا) عند إنشاء نماذج السجل الفعال. تصب الفكرة في حال هيأت تطبيقك بالطريقة ذاتها معظم الوقت، فتلك الطريقة يجب أن تكون الطريقة الافتراضية. لذلك، ستحتاج إلى التهيئات الصريحة فقط في تلك الحالات التي لا تستطيع فيها التقيّد بالأعراف المعيارية (standard convention).
عند كتابة التطبيقات باستخدام لغات برمجة أو واجهات عمل أخرى، قد يكون من الضروري كتابة الكثير من تعليمات التهيئة والضبط الضرورية لعمل التطبيق. يعد ذلك صحيحًا من أجل واجهات عمل ORM بشكل عام. لكن إذا اتبعت العرف المتبنى من قبل ريلز، فستحتاج إلى كتابة القليل من تعليمات التهيئة (وبعض الأوقات قد لا تحتاج إلى كتابة تهيئة مطلقًا) عند إنشاء نماذج Active Record. تصب الفكرة في حال هيأت تطبيقك بالطريقة ذاتها معظم الوقت، فتلك الطريقة يجب أن تكون الطريقة الافتراضية. لذلك، ستحتاج إلى التهيئات الصريحة فقط في تلك الحالات التي لا تستطيع فيها التقيّد بالأعراف المعيارية (standard convention).


=== أعراف التسمية ===
=== أعراف التسمية ===
بشكل افتراضي، يستخدم السجل الفعال بعض أعراف (اصطلاحات) التسمية للحاجة إلى الربط بين النماذج وجداول قاعدة البيانات. يجمع ريلز أسماء الأصناف لمعرفة أسماء الجداول. لذا، من أجل الصنف <code>Book</code>، يجب أن تنشئ جدولًا في قاعدة البيانات يسمّى <code>books</code>. تعد طريقة الجمع الخاصة بريلز طريقةً قويةً جدًا، والتي تمكّنك من جمع الكلمات النظامية والشاذة. عند استخدام أسماء الأصناف المكوّنة من كلمتين أو أكثر، يجب أن يراعي اسم النموذج أعراف لغة [[Ruby|روبي]]، وذلك باستخدام نمط سنام الجمل (CamelCase)، بينما يجب على أسماء الجداول أن تحوي الكلمات مفصولة بواسطة علامة الترقيم "_". أمثلة:
بشكل افتراضي، يستخدم Active Record بعض أعراف (اصطلاحات) التسمية للحاجة إلى الربط بين النماذج وجداول قاعدة البيانات. يجمع ريلز أسماء الأصناف لمعرفة أسماء الجداول. لذا، من أجل الصنف <code>Book</code>، يجب أن تنشئ جدولًا في قاعدة البيانات يسمّى <code>books</code>. تعد طريقة الجمع الخاصة بريلز طريقةً قويةً جدًا، والتي تمكّنك من جمع الكلمات النظامية والشاذة. عند استخدام أسماء الأصناف المكوّنة من كلمتين أو أكثر، يجب أن يراعي اسم النموذج أعراف لغة [[Ruby|روبي]]، وذلك باستخدام نمط سنام الجمل (CamelCase)، بينما يجب على أسماء الجداول أن تحوي الكلمات مفصولة بواسطة علامة الترقيم "_". أمثلة:
* جدول قاعدة بيانات: جمع مع علامة ترقيم "_" تفصل الكلمات (مثال: book_clubs).
* جدول قاعدة بيانات: جمع مع علامة ترقيم "_" تفصل الكلمات (مثال: book_clubs).
* صنف النموذج <code>Model</code>: مفرد مع أول حرف كبير من كل كلمة (مثال: BookClub).
* صنف النموذج <code>Model</code>: مفرد مع أول حرف كبير من كل كلمة (مثال: BookClub).
سطر 56: سطر 56:


=== أعراف المخطط ===
=== أعراف المخطط ===
يستخدم السجل الفعال بعض أعراف التسمية من أجل الحقول في قواعد البيانات، وذلك بناءً على الهدف من هذه الحقول.
يستخدم Active Record بعض أعراف التسمية من أجل الحقول في قواعد البيانات، وذلك بناءً على الهدف من هذه الحقول.
* المفاتيح الأجنبية (Foreign keys): يجب على هذه الحقول أن تراعي النمط التالي "مُعرِّف_اسم_الجدول_المفرد_id" (مثال: item_id، order_id). هذه هي الحقول التي يجب على السجل الفعال النظر إليها عند إنشاء العلاقات بين النماذج.
* المفاتيح الأجنبية (Foreign keys): يجب على هذه الحقول أن تراعي النمط التالي "مُعرِّف_اسم_الجدول_المفرد_id" (مثال: item_id، order_id). هذه هي الحقول التي يجب على Active Record النظر إليها عند إنشاء العلاقات بين النماذج.
* المفاتيح الرئيسية (Primary keys): بشكل افتراضي، يستخدم السجل الفعال حقل العدد الصحيح المسمى id كالمفتاح الرئيسي للجدول. عند استخدام [[Rails/active record migrations|ترحيلات السجل الفعال]] لإنشاء جداولك، سيتم إنشاء هذا الحقل تلقائيًا.
* المفاتيح الرئيسية (Primary keys): بشكل افتراضي، يستخدم Active Record حقل العدد الصحيح المسمى id كالمفتاح الرئيسي للجدول. عند استخدام [[Rails/active record migrations|ترحيلات Active Record]] لإنشاء جداولك، سيتم إنشاء هذا الحقل تلقائيًا.
هناك مجموعة من الحقول الاختيارية التي تضيف ميزات إضافية إلى كائنات السجل الفعال:
هناك مجموعة من الحقول الاختيارية التي تضيف ميزات إضافية إلى كائنات Active Record:
* الحقل <code>created_at</code>: يعيّن تلقائيًا تاريخ إنشاء السجل.
* الحقل <code>created_at</code>: يعيّن تلقائيًا تاريخ إنشاء السجل.
* الحقل <code>updated_at</code>: يعيّن تلقائيًا تاريخ تعديل السجل.
* الحقل <code>updated_at</code>: يعيّن تلقائيًا تاريخ تعديل السجل.
سطر 66: سطر 66:
* الحقل <code>‎(association_name)_type</code>: يخزن النوع من أجل العلاقات متعددة الأشكال.
* الحقل <code>‎(association_name)_type</code>: يخزن النوع من أجل العلاقات متعددة الأشكال.
* الحقل <code>‎(table_name)_count</code>: يستخدم للتخزين المؤقت لعدد الكائنات المرتبطة في العلاقات. مثلًا، إن الحقل <code>comments_count</code> في الصنف <code>Article</code> الذي يملك عدة نُسخ من <code>Comment</code> سيخزّن عدد التعليقات المرتبطة بكل مقالة.
* الحقل <code>‎(table_name)_count</code>: يستخدم للتخزين المؤقت لعدد الكائنات المرتبطة في العلاقات. مثلًا، إن الحقل <code>comments_count</code> في الصنف <code>Article</code> الذي يملك عدة نُسخ من <code>Comment</code> سيخزّن عدد التعليقات المرتبطة بكل مقالة.
'''ملاحظة''': في حين أن هذه الحقول اختيارية، فهي حقيقةً محجوزةً من قبل السجل الفعال. تجنب تسمية الحقول بأسماء محجوزة إلى في حال أردت المزيد من الفعالية. مثلًا، الكلمة <code>type</code> هي كلمة محجوزة تستخدم لوراثة الجدول الوحيد. في حال لم تكن مستخدمًا لهذه الوراثة، حاول المجيء بأسماء مختلفة مثل "context"، والتي تعبر بشكل دقيق عن البيانات التي تُنمذَج (modeling).
'''ملاحظة''': في حين أن هذه الحقول اختيارية، فهي حقيقةً محجوزةً من قبل Active Record. تجنب تسمية الحقول بأسماء محجوزة إلى في حال أردت المزيد من الفعالية. مثلًا، الكلمة <code>type</code> هي كلمة محجوزة تستخدم لوراثة الجدول الوحيد. في حال لم تكن مستخدمًا لهذه الوراثة، حاول المجيء بأسماء مختلفة مثل "context"، والتي تعبر بشكل دقيق عن البيانات التي تُنمذَج (modeling).


== إنشاء نماذج السجل الفعال ==
== إنشاء نماذج Active Record ==
من السهل جدًا إنشاء نماذج السجل الفعال. كل ما يتوجب عليك فعله هو إنشاء صنف فرعي يرث من الصنف <code>ApplicationRecord</code>:<syntaxhighlight lang="rails">
من السهل جدًا إنشاء نماذج Active Record. كل ما يتوجب عليك فعله هو إنشاء صنف فرعي يرث من الصنف <code>ApplicationRecord</code>:<syntaxhighlight lang="rails">
class Product < ApplicationRecord
class Product < ApplicationRecord
end
end
سطر 105: سطر 105:


== العمليات CRUD: قراءة وكتابة البيانات ==
== العمليات CRUD: قراءة وكتابة البيانات ==
المصطلح CRUD هو اختصار لأربع عمليات مستخدمة على البيانات: إنشاء (Create)، قراءة (Read)، تحديث (Update)، وحذف (Delete). تلقائيًا، ينشئ السجل الفعال توابعًا لإتاحة قراء وكتابة البيانات المخزنة في قواعد البيانات.
المصطلح CRUD هو اختصار لأربع عمليات مستخدمة على البيانات: إنشاء (Create)، قراءة (Read)، تحديث (Update)، وحذف (Delete). تلقائيًا، ينشئ Active Record توابعًا لإتاحة قراء وكتابة البيانات المخزنة في قواعد البيانات.


=== الإنشاء ===
=== الإنشاء ===
يمكن إنشاء كائنات السجل الفعال من [[Ruby/Hash|جدول Hash]] أو كتلة أو من خلال تعيين الخاصيات بشكل يدوي بعد الإنشاء. يعيد التابع <code>new</code> كائنًا جديدًا، بينما يعيد التابع <code>create</code> الكائن ويحفظه مباشرةً في قاعدة البيانات.
يمكن إنشاء كائنات Active Record من [[Ruby/Hash|جدول Hash]] أو كتلة أو من خلال تعيين الخاصيات بشكل يدوي بعد الإنشاء. يعيد التابع <code>new</code> كائنًا جديدًا، بينما يعيد التابع <code>create</code> الكائن ويحفظه مباشرةً في قاعدة البيانات.


على سبيل المثال، بفرض النموذج <code>User</code> الذي يحوي على الخاصيات <code>name</code> و <code>occupation</code>، يمكن استخدام التابع <code>create</code> لإنشاء وحفظ سجل جديد في قاعدة البيانات.<syntaxhighlight lang="rails">
على سبيل المثال، بفرض النموذج <code>User</code> الذي يحوي على الخاصيات <code>name</code> و <code>occupation</code>، يمكن استخدام التابع <code>create</code> لإنشاء وحفظ سجل جديد في قاعدة البيانات.<syntaxhighlight lang="rails">
سطر 126: سطر 126:


=== القراءة ===
=== القراءة ===
يزوّد السجل الفعال بواجهة برمجية غنية من أجل قراءة البيانات من قواعد البيانات. فيما يلي مجموعة من الأمثلة المختلفة حول وصول البيانات المزودة من قبل السجل الفعال:<syntaxhighlight lang="rails">
يزوّد Active Record بواجهة برمجية غنية من أجل قراءة البيانات من قواعد البيانات. فيما يلي مجموعة من الأمثلة المختلفة حول وصول البيانات المزودة من قبل Active Record:<syntaxhighlight lang="rails">
# تعيد مجموعة تحوي كل المستخدمين
# تعيد مجموعة تحوي كل المستخدمين
users = User.all
users = User.all
سطر 141: سطر 141:




</syntaxhighlight>يمكنك قراءة المزيد حول الاستعلامات باستخدام السجل الفعال في توثيق [[Rails/active record querying|واجهة استعلامات السجل الفعال]].
</syntaxhighlight>يمكنك قراءة المزيد حول الاستعلامات باستخدام Active Record في توثيق [[Rails/active record querying|واجهة استعلامات Active Record]].


=== التحديث ===
=== التحديث ===
بعد إعادة كائن السجل الفعال، يمكن تعديل خاصياته ومن ثم حفظه في قاعدة البيانات:<syntaxhighlight lang="rails">
بعد إعادة كائن Active Record، يمكن تعديل خاصياته ومن ثم حفظه في قاعدة البيانات:<syntaxhighlight lang="rails">
user = User.find_by(name: 'David')
user = User.find_by(name: 'David')
user.name = 'Dave'
user.name = 'Dave'
سطر 156: سطر 156:


=== الحذف ===
=== الحذف ===
بالمثل، عند استرجاع كائن السجل الفعال، يمكن حذفه من قاعدة البيانات كالتالي:<syntaxhighlight lang="rails">
بالمثل، عند استرجاع كائن Active Record، يمكن حذفه من قاعدة البيانات كالتالي:<syntaxhighlight lang="rails">
user = User.find_by(name: 'David')
user = User.find_by(name: 'David')
user.destroy
user.destroy
سطر 170: سطر 170:


== التحقق ==
== التحقق ==
يمكنك السجل الفعال من التحقق من حالة السجل قبل حفظه في قاعدة البيانات. هناك مجموعة من الطرق التي يمكنك استخدامها للتحقق من سجلك والتأكد من أن الخاصيات ليست فارغة، أو ليست مكررة، أو تتبع نسق معين، والمزيد من عمليات التحقق.
يمكنك Active Record من التحقق من حالة السجل قبل حفظه في قاعدة البيانات. هناك مجموعة من الطرق التي يمكنك استخدامها للتحقق من سجلك والتأكد من أن الخاصيات ليست فارغة، أو ليست مكررة، أو تتبع نسق معين، والمزيد من عمليات التحقق.


إن عملية التحقق من صحة السجلات هي عملية مهمة جدًا عند الحفظ في قاعدة البيانات، وبالتالي يأخذ التابع <code>save</code> و <code>update</code> هذه العمليات بالحسبان عند العمل: إذ يعيد هذين التابعين القيمة <code>false</code> عند فشل التحقق، ولا تنفذ أية عمليات على قاعدة البيانات. يمكن تجاوز هذا التصرف عن طريق التابعين <code>save!‎</code> و <code>update!‎</code>، التي تعتبر أشد وأكثر صرامة، إذ ترمي استثناءً من النوع <code>ActiveRecord::RecordInvalid</code> في حال فشل عملية التحقق. على سبيل المثال:<syntaxhighlight lang="rails">
إن عملية التحقق من صحة السجلات هي عملية مهمة جدًا عند الحفظ في قاعدة البيانات، وبالتالي يأخذ التابع <code>save</code> و <code>update</code> هذه العمليات بالحسبان عند العمل: إذ يعيد هذين التابعين القيمة <code>false</code> عند فشل التحقق، ولا تنفذ أية عمليات على قاعدة البيانات. يمكن تجاوز هذا التصرف عن طريق التابعين <code>save!‎</code> و <code>update!‎</code>، التي تعتبر أشد وأكثر صرامة، إذ ترمي استثناءً من النوع <code>ActiveRecord::RecordInvalid</code> في حال فشل عملية التحقق. على سبيل المثال:<syntaxhighlight lang="rails">
سطر 184: سطر 184:


== توابع رد النداء (Callbacks) ==
== توابع رد النداء (Callbacks) ==
تتيح توابع رد النداء الخاصة بالسجل الفعال إمكانية ربط تعليمات معينة بأحداث مخصصة في دورة حياة النموذج. يمكّنك ذلك من إضافة السلوك لنماذجك عن طريق تنفيذ التعليمات بشكل خفي عند إطلاق هذه الأحداث، مثلًا عند إنشاء سجل جديد، أو تحديثه أو حذفه. يمكنك تعلم المزيد عن توابع رد النداء في دليل [[Rails/active record callbacks|ردود نداء السجل الفعال]].
تتيح توابع رد النداء الخاصة بـ Active Record إمكانية ربط تعليمات معينة بأحداث مخصصة في دورة حياة النموذج. يمكّنك ذلك من إضافة السلوك لنماذجك عن طريق تنفيذ التعليمات بشكل خفي عند إطلاق هذه الأحداث، مثلًا عند إنشاء سجل جديد، أو تحديثه أو حذفه. يمكنك تعلم المزيد عن توابع رد النداء في دليل [[Rails/active record callbacks|ردود نداء Active Record]].


== التهجيرات ==
== التهجيرات ==
يزوّد ريلز بلغة ذات نطاق لإدارة مخططات قواعد البيانات التي تدعى "بالتهجيرات" (migrations). تُخزّن التهجيرات في ملفات، وتنفّذ على قواعد البيانات التي يدعمها السجل الفعال بواسطة <code>rake</code>. في الملف التالي تهجير ينشئ جدولًا:<syntaxhighlight lang="rails">
يزوّد ريلز بلغة ذات نطاق لإدارة مخططات قواعد البيانات التي تدعى "بالتهجيرات" (migrations). تُخزّن التهجيرات في ملفات، وتنفّذ على قواعد البيانات التي يدعمها Active Record بواسطة <code>rake</code>. في الملف التالي تهجير ينشئ جدولًا:<syntaxhighlight lang="rails">
class CreatePublications < ActiveRecord::Migration[5.0]
class CreatePublications < ActiveRecord::Migration[5.0]
   def change
   def change
سطر 205: سطر 205:
</syntaxhighlight>يستمر ريلز في تعقُّب حالة الملفات المحفوظة في قاعدة البيانات، ويزوّد بطريقة لإعادة حالة التهجير. لتنفيذ التهجير، يمكنك استخدام الأمر <code>rails db:migrate</code>، ولإعادته، يمكنك استخدام الأمر <code>rails db:rollback</code>.
</syntaxhighlight>يستمر ريلز في تعقُّب حالة الملفات المحفوظة في قاعدة البيانات، ويزوّد بطريقة لإعادة حالة التهجير. لتنفيذ التهجير، يمكنك استخدام الأمر <code>rails db:migrate</code>، ولإعادته، يمكنك استخدام الأمر <code>rails db:rollback</code>.


الجدير بالملاحظة أنَّ التعليمات السابقة هي حيادية لقواعد البيانات، إذ يمكن تنفيذها على قواعد البيانات من نوع MySQL أو PostgreSQL أو Oracle أو العديد من قواعد البيانات الأخرى. يمكنك تعلّم المزيد عن التهجيرات في دليل [[Rails/active record migrations|التهجيرات الخاصة بالسجل الفعال]].
الجدير بالملاحظة أنَّ التعليمات السابقة هي حيادية لقواعد البيانات، إذ يمكن تنفيذها على قواعد البيانات من نوع MySQL أو PostgreSQL أو Oracle أو العديد من قواعد البيانات الأخرى. يمكنك تعلّم المزيد عن التهجيرات في دليل [[Rails/active record migrations|التهجيرات الخاصة بActive Record]].


== مصادر ==
== مصادر ==
* [https://guides.rubyonrails.org/active_record_basics.html صفحة Active Record Basics في توثيق Ruby on Rails الرسمي.]
* [https://guides.rubyonrails.org/active_record_basics.html صفحة Active Record Basics في توثيق Ruby on Rails الرسمي.]

مراجعة 16:16، 19 مارس 2019

هذا الدليل هو مدخل إلى المكتبة Active Record. بعد قراءة هذا الدليل، ستتعرف على:

  • ما هي تقنية ORM (اختصار للعبارة Object Relational Mapping أي "ربط الكائنات العِلاقيَّة") والسجل الفعَّال وكيفية استعمالهما في ريلز.
  • كيف ينسجم السجل الفعَّال مع النموذج MVC (اختصار للعبارة Model-View-Controller).
  • كيفية استعمال نماذج السجل الفعَّال (Active Record models) لمعالجة وتعديل البيانات المخزَّنة في قاعدة بيانات عِلاقيِّة (relational database).
  • اصطلاحات تسمية مخطَّط السجل الفعَّال.
  • مفهوم تهجيرات، وتحققات، وردود نداء قاعدة البيانات.

ما هو Active Record؟

إن Active Record هو الحرف M في MVC - أي "النموذج" (Model)، الذي يعبر عن الطبقة المسؤولة عن تمثيل منطق العمل وبياناته في النظام. يسهّل Active Record عمليّة إنشاء واستخدام الكائنات التي يجب المحافظة على بياناتها في قاعدة بيانات. Active Record هو تنفيذ "لنمط Active Record"، والذي يعبر بذاته عن نظام ربط الكائنات بالعلاقات (Object Relational Mapping).

نمط Active Record

شُرح نمط عمل Active Record من قبل مارتن فولر (Martin Fowler) في كتابه "أنماط معمارية التطبيقات المؤسساتية" (Patterns of Enterprise Application Architecture). في Active Record، تحمل الكائنات البيانات المحفوظة والسلوك المنفذ على هذه البيانات. يأخذ Active Record بالحسبان الرأي الذي ينص على أن ضمان الوصول للبيانات عبر جزء من الكائن سيجعل المستخدمين على دراية بهذا الكائن وكيفية قراءة وكتابة البيانات من وعلى قاعدة البيانات.

ربط الكائنات بالعلاقات

إن ربط الكائنات بالعلاقات، وكما يُرمز له اختصارًا ORM، هو عبارة عن طريقة لربط الكائنات الخاصة بتطبيقٍ ما بجداول في نظام إدارة قواعد بيانات علائقية. باستخدام هذا النظام، يمكن تخزين وقراءة الخاصيات والعلاقات من قاعدة البيانات بسهولة دون الحاجة لكتابة تعليمات SQL مباشرةً.

ملاحظة: إذا لم تكن ملمًا بأنظمة إدارة قواعد البيانات العلائقية، أو بلغة الاستعلام البنيوية SQL، يرجى الاطلاع على توثيق لغة SQL أو الاطلاع هذا المقال (والمقالات الأخرى حول SQL في أكاديمية حسوب). إن فهم طريقة عمل قواعد البيانات العلائقية مهم جدًا لفهم السجلات الفعالة في ريلز بشكل عام.

Active Record كإطار عمل ORM

يزوّد Active Record بمجموعة من المهام، أهمها القابلية على:

  • تمثيل النماذج (models) وبياناتها.
  • تمثيل العلاقات بين هذه النماذج.
  • تمثيل هيكلية الوراثة الهرمية (inheritance hierarchies) بين النماذج المتعددة.
  • التحقق من النماذج قبل حفظها في قاعدة البيانات.
  • تنفيذ عمليات قواعد البيانات بشكل غرضي التوجه.

العرف فوق الضبط في Active Record

عند كتابة التطبيقات باستخدام لغات برمجة أو واجهات عمل أخرى، قد يكون من الضروري كتابة الكثير من تعليمات التهيئة والضبط الضرورية لعمل التطبيق. يعد ذلك صحيحًا من أجل واجهات عمل ORM بشكل عام. لكن إذا اتبعت العرف المتبنى من قبل ريلز، فستحتاج إلى كتابة القليل من تعليمات التهيئة (وبعض الأوقات قد لا تحتاج إلى كتابة تهيئة مطلقًا) عند إنشاء نماذج Active Record. تصب الفكرة في حال هيأت تطبيقك بالطريقة ذاتها معظم الوقت، فتلك الطريقة يجب أن تكون الطريقة الافتراضية. لذلك، ستحتاج إلى التهيئات الصريحة فقط في تلك الحالات التي لا تستطيع فيها التقيّد بالأعراف المعيارية (standard convention).

أعراف التسمية

بشكل افتراضي، يستخدم Active Record بعض أعراف (اصطلاحات) التسمية للحاجة إلى الربط بين النماذج وجداول قاعدة البيانات. يجمع ريلز أسماء الأصناف لمعرفة أسماء الجداول. لذا، من أجل الصنف Book، يجب أن تنشئ جدولًا في قاعدة البيانات يسمّى books. تعد طريقة الجمع الخاصة بريلز طريقةً قويةً جدًا، والتي تمكّنك من جمع الكلمات النظامية والشاذة. عند استخدام أسماء الأصناف المكوّنة من كلمتين أو أكثر، يجب أن يراعي اسم النموذج أعراف لغة روبي، وذلك باستخدام نمط سنام الجمل (CamelCase)، بينما يجب على أسماء الجداول أن تحوي الكلمات مفصولة بواسطة علامة الترقيم "_". أمثلة:

  • جدول قاعدة بيانات: جمع مع علامة ترقيم "_" تفصل الكلمات (مثال: book_clubs).
  • صنف النموذج Model: مفرد مع أول حرف كبير من كل كلمة (مثال: BookClub).
النموذج/الصنف الجدول/المخطط
Article articles
LineItem line_items
Deer deers
Mouse mice
Person people

أعراف المخطط

يستخدم Active Record بعض أعراف التسمية من أجل الحقول في قواعد البيانات، وذلك بناءً على الهدف من هذه الحقول.

  • المفاتيح الأجنبية (Foreign keys): يجب على هذه الحقول أن تراعي النمط التالي "مُعرِّف_اسم_الجدول_المفرد_id" (مثال: item_id، order_id). هذه هي الحقول التي يجب على Active Record النظر إليها عند إنشاء العلاقات بين النماذج.
  • المفاتيح الرئيسية (Primary keys): بشكل افتراضي، يستخدم Active Record حقل العدد الصحيح المسمى id كالمفتاح الرئيسي للجدول. عند استخدام ترحيلات Active Record لإنشاء جداولك، سيتم إنشاء هذا الحقل تلقائيًا.

هناك مجموعة من الحقول الاختيارية التي تضيف ميزات إضافية إلى كائنات Active Record:

  • الحقل created_at: يعيّن تلقائيًا تاريخ إنشاء السجل.
  • الحقل updated_at: يعيّن تلقائيًا تاريخ تعديل السجل.
  • الحقل lock_version: يضيف القفل الذكي إلى نموذج.
  • الحقل type: يحدّد أن النموذج يستخدم وراثة الجدول الوحيد.
  • الحقل ‎(association_name)_type: يخزن النوع من أجل العلاقات متعددة الأشكال.
  • الحقل ‎(table_name)_count: يستخدم للتخزين المؤقت لعدد الكائنات المرتبطة في العلاقات. مثلًا، إن الحقل comments_count في الصنف Article الذي يملك عدة نُسخ من Comment سيخزّن عدد التعليقات المرتبطة بكل مقالة.

ملاحظة: في حين أن هذه الحقول اختيارية، فهي حقيقةً محجوزةً من قبل Active Record. تجنب تسمية الحقول بأسماء محجوزة إلى في حال أردت المزيد من الفعالية. مثلًا، الكلمة type هي كلمة محجوزة تستخدم لوراثة الجدول الوحيد. في حال لم تكن مستخدمًا لهذه الوراثة، حاول المجيء بأسماء مختلفة مثل "context"، والتي تعبر بشكل دقيق عن البيانات التي تُنمذَج (modeling).

إنشاء نماذج Active Record

من السهل جدًا إنشاء نماذج Active Record. كل ما يتوجب عليك فعله هو إنشاء صنف فرعي يرث من الصنف ApplicationRecord:

class Product < ApplicationRecord
end

سينشئ هذا النموذج Product، الذي يربط بالجدول products في قاعدة البيانات. عن طريق هذا الصنف، يمكنك أيضًا ربط الحقول في كل سطر من أسطر الجدول بخاصّيات ضمن النموذج. بفرض أن الجدول products تم إنشاؤه عن طريق تنفيذ تعليمة SQL التالية:

CREATE TABLE products (
   id int(11) NOT NULL auto_increment,
   name varchar(255),
   PRIMARY KEY  (id)
);

تنشئ هذه التعليمة جدولًا بعمودين، id و name. كل سطر من هذا العامود يمثل منتجًا بهذين الوسيطين. وبالتالي، عليك أن تكتب التعليمات التالية لإنشاء سطر جديد:

p = Product.new
p.name = "Some Book"
puts p.name # "Some Book"

تجاوز أعراف التسمية

ماذا لو أردت اتباع أعراف تسمية مختلفة أو أردت استخدام تطبيقك المكتوب بريلز مع قاعدة بيانات قديمة؟ ليست مشكلة، يمكنك بسهولة تجاوز أعراف التسمية.

يرث الصنف ApplicationRecord من الصنف ActiveRecord::Base، الذي يعرّف مجموعة من الطرق المساعدة. يمكنك استخدام التابع ActiveRecord::Base.table_name=‎ لتحديد اسم الجدول الذي يجب استخدامه.

class Product < ApplicationRecord
  self.table_name = "my_products"
end

إذا فعلت ذلك، عليك أن تحدد بشكل يدوي اسم الصنف الذي يحوي التجهيزات (my_products.yml)، باستخدام التابع set_fixture_class في تعريف الاختبار:

class ProductTest < ActiveSupport::TestCase
  set_fixture_class my_products: Product
  fixtures :my_products
  ...
end

من الممكن تجاوز العمود الذي يستخدم مفتاحًا رئيسيًا للجدول باستخدام التابع ActiveRecord::Base.primary_key:

class Product < ApplicationRecord
  self.primary_key = "product_id"
end

العمليات CRUD: قراءة وكتابة البيانات

المصطلح CRUD هو اختصار لأربع عمليات مستخدمة على البيانات: إنشاء (Create)، قراءة (Read)، تحديث (Update)، وحذف (Delete). تلقائيًا، ينشئ Active Record توابعًا لإتاحة قراء وكتابة البيانات المخزنة في قواعد البيانات.

الإنشاء

يمكن إنشاء كائنات Active Record من جدول Hash أو كتلة أو من خلال تعيين الخاصيات بشكل يدوي بعد الإنشاء. يعيد التابع new كائنًا جديدًا، بينما يعيد التابع create الكائن ويحفظه مباشرةً في قاعدة البيانات.

على سبيل المثال، بفرض النموذج User الذي يحوي على الخاصيات name و occupation، يمكن استخدام التابع create لإنشاء وحفظ سجل جديد في قاعدة البيانات.

user = User.create(name: "David", occupation: "Code Artist")

أما باستخدام التابع new، يمكن إنشاء الكائن دون حفظه في قاعدة البيانات.

user = User.new
user.name = "David"
user.occupation = "Code Artist"

بعد ذلك، يمكن حفظ السجل في قاعدة البيانات باستخدام التابع user.save. أخيرًا وليس آخرًا، إذا تم إعطاء كتلةٍ، فالكائن الجديد الناتج عن التابعين create و new يمرَّر إلى تلك كتلة من أجل عملية التهيئة:

user = User.new do |u|
  u.name = "David"
  u.occupation = "Code Artist"
end

القراءة

يزوّد Active Record بواجهة برمجية غنية من أجل قراءة البيانات من قواعد البيانات. فيما يلي مجموعة من الأمثلة المختلفة حول وصول البيانات المزودة من قبل Active Record:

# تعيد مجموعة تحوي كل المستخدمين
users = User.all

# تعيد أول مستخدم
user = User.first

# David تعيد أول مستخدم اسمه
david = User.find_by(name: 'David')

# Code Artists والأعمال David البحث عن جميع المستخدمين ذوي الأسماء   
# تنازليًا created_at والترتيب بواسطة الحقل  
users = User.where(name: 'David', occupation: 'Code Artist').order(created_at: :desc)

يمكنك قراءة المزيد حول الاستعلامات باستخدام Active Record في توثيق واجهة استعلامات Active Record.

التحديث

بعد إعادة كائن Active Record، يمكن تعديل خاصياته ومن ثم حفظه في قاعدة البيانات:

user = User.find_by(name: 'David')
user.name = 'Dave'
user.save

اختصارًا لهذه التعليمات، يمكن استخدام الطريقة التالية:

user = User.find_by(name: 'David')
user.update(name: 'Dave')

يكون هذا مفيدًا عند تحديث مجموعة من الخاصيات بآن واحد. في حال أردت تحديث مجموعة من السجلات بدفعة واحدة، يمكنك استخدام التابع update_all.

User.update_all "max_login_attempts = 3, must_change_password = 'true'"

الحذف

بالمثل، عند استرجاع كائن Active Record، يمكن حذفه من قاعدة البيانات كالتالي:

user = User.find_by(name: 'David')
user.destroy

في حال أردت حذف مجموعة من السجلات دفعة واحدة، يمكنك استخدام التابع destroy_all.

# وحذفه David البحث عن المستخدم ذي الاسم
User.where(name: 'David').destroy_all

# حذف جميع المستخدمين
User.destroy_all

التحقق

يمكنك Active Record من التحقق من حالة السجل قبل حفظه في قاعدة البيانات. هناك مجموعة من الطرق التي يمكنك استخدامها للتحقق من سجلك والتأكد من أن الخاصيات ليست فارغة، أو ليست مكررة، أو تتبع نسق معين، والمزيد من عمليات التحقق.

إن عملية التحقق من صحة السجلات هي عملية مهمة جدًا عند الحفظ في قاعدة البيانات، وبالتالي يأخذ التابع save و update هذه العمليات بالحسبان عند العمل: إذ يعيد هذين التابعين القيمة false عند فشل التحقق، ولا تنفذ أية عمليات على قاعدة البيانات. يمكن تجاوز هذا التصرف عن طريق التابعين save!‎ و update!‎، التي تعتبر أشد وأكثر صرامة، إذ ترمي استثناءً من النوع ActiveRecord::RecordInvalid في حال فشل عملية التحقق. على سبيل المثال:


class User < ApplicationRecord
  validates :name, presence: true
end
 
user = User.new
user.save  # => false
user.save! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank

يمكنك قراءة المزيد حول هذا الموضوع في دليل التحقق من صحة السجل الفعَّال.

توابع رد النداء (Callbacks)

تتيح توابع رد النداء الخاصة بـ Active Record إمكانية ربط تعليمات معينة بأحداث مخصصة في دورة حياة النموذج. يمكّنك ذلك من إضافة السلوك لنماذجك عن طريق تنفيذ التعليمات بشكل خفي عند إطلاق هذه الأحداث، مثلًا عند إنشاء سجل جديد، أو تحديثه أو حذفه. يمكنك تعلم المزيد عن توابع رد النداء في دليل ردود نداء Active Record.

التهجيرات

يزوّد ريلز بلغة ذات نطاق لإدارة مخططات قواعد البيانات التي تدعى "بالتهجيرات" (migrations). تُخزّن التهجيرات في ملفات، وتنفّذ على قواعد البيانات التي يدعمها Active Record بواسطة rake. في الملف التالي تهجير ينشئ جدولًا:

class CreatePublications < ActiveRecord::Migration[5.0]
  def change
    create_table :publications do |t|
      t.string :title
      t.text :description
      t.references :publication_type
      t.integer :publisher_id
      t.string :publisher_type
      t.boolean :single_issue
 
      t.timestamps
    end
    add_index :publications, :publication_type_id
  end
end

يستمر ريلز في تعقُّب حالة الملفات المحفوظة في قاعدة البيانات، ويزوّد بطريقة لإعادة حالة التهجير. لتنفيذ التهجير، يمكنك استخدام الأمر rails db:migrate، ولإعادته، يمكنك استخدام الأمر rails db:rollback.

الجدير بالملاحظة أنَّ التعليمات السابقة هي حيادية لقواعد البيانات، إذ يمكن تنفيذها على قواعد البيانات من نوع MySQL أو PostgreSQL أو Oracle أو العديد من قواعد البيانات الأخرى. يمكنك تعلّم المزيد عن التهجيرات في دليل التهجيرات الخاصة بActive Record.

مصادر