الفرق بين المراجعتين لصفحة: «Rails/active record basics»
جميل-بيلوني (نقاش | مساهمات) |
جميل-بيلوني (نقاش | مساهمات) طلا ملخص تعديل |
||
(3 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:أساسيات | <noinclude>{{DISPLAYTITLE:أساسيات Active Record في ريلز}}</noinclude> | ||
[[تصنيف:Rails]] | [[تصنيف:Rails]] | ||
هذا الدليل هو مدخل إلى | [[تصنيف:Rails Models]] | ||
* ما هي تقنية ORM (اختصار للعبارة Object Relational Mapping أي "ربط الكائنات العِلاقيَّة") | هذا الدليل هو مدخل إلى المكتبة Active Record. بعد قراءة هذا الدليل، ستتعرف على: | ||
* كيف ينسجم | * ما هي تقنية ORM (اختصار للعبارة Object Relational Mapping أي "ربط الكائنات العِلاقيَّة") وما هو [[Rails/active record|Active Record]] وكيفية استعمالهما في ريلز. | ||
* كيفية استعمال نماذج | * كيف ينسجم [[Rails/active record|Active Record]] مع النموذج MVC (اختصار للعبارة Model-View-Controller). | ||
* اصطلاحات تسمية مخطَّط | * كيفية استعمال نماذج [[Rails/active record|Active Record]] (أي Active Record models) لمعالجة وتعديل البيانات المخزَّنة في قاعدة بيانات عِلاقيِّة (relational database). | ||
* اصطلاحات تسمية مخطَّط [[Rails/active record|Active Record]]. | |||
* مفهوم تهجيرات، وتحققات، وردود نداء قاعدة البيانات. | * مفهوم تهجيرات، وتحققات، وردود نداء قاعدة البيانات. | ||
== ما هو | == ما هو Active Record؟ == | ||
إن | إن [[Rails/active record|Active Record]] هو الحرف M في [[wikipedia:Model–view–controller|MVC]] - أي "النموذج" (Model)، الذي يعبر عن الطبقة المسؤولة عن تمثيل منطق العمل وبياناته في النظام. يسهّل [[Rails/active record|Active Record]] عمليّة إنشاء واستخدام الكائنات التي يجب المحافظة على بياناتها في قاعدة بيانات. [[Rails/active record|Active Record]] هو تنفيذ "[[wikipedia:Active_record_pattern|لنمط Active Record]]"، والذي يعبر بذاته عن نظام ربط الكائنات بالعلاقات (Object Relational Mapping). | ||
=== نمط | === نمط Active Record === | ||
شُرح [http://www.martinfowler.com/eaaCatalog/activeRecord.html نمط عمل | شُرح [http://www.martinfowler.com/eaaCatalog/activeRecord.html نمط عمل Active Record] من قبل مارتن فولر (Martin Fowler) في كتابه "أنماط معمارية التطبيقات المؤسساتية" (Patterns of Enterprise Application Architecture). في [[Rails/active record|Active Record]]، تحمل الكائنات البيانات المحفوظة والسلوك المنفذ على هذه البيانات. يأخذ [[Rails/active record|Active Record]] بالحسبان الرأي الذي ينص على أن ضمان الوصول للبيانات عبر جزء من الكائن سيجعل المستخدمين على دراية بهذا الكائن وكيفية قراءة وكتابة البيانات من وعلى قاعدة البيانات. | ||
=== ربط الكائنات بالعلاقات === | === ربط الكائنات بالعلاقات === | ||
إن ربط الكائنات بالعلاقات، وكما يُرمز له اختصارًا ORM، هو عبارة عن طريقة لربط الكائنات الخاصة بتطبيقٍ ما بجداول في نظام إدارة قواعد بيانات علائقية. باستخدام هذا النظام، يمكن تخزين وقراءة الخاصيات والعلاقات من قاعدة البيانات بسهولة دون الحاجة لكتابة تعليمات SQL مباشرةً. | إن ربط الكائنات بالعلاقات، وكما يُرمز له اختصارًا ORM، هو عبارة عن طريقة لربط الكائنات الخاصة بتطبيقٍ ما بجداول في نظام إدارة قواعد بيانات علائقية. باستخدام هذا النظام، يمكن تخزين وقراءة الخاصيات والعلاقات من قاعدة البيانات بسهولة دون الحاجة لكتابة تعليمات SQL مباشرةً. | ||
'''ملاحظة''': إذا لم تكن ملمًا بأنظمة إدارة قواعد البيانات العلائقية، أو بلغة الاستعلام البنيوية [[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 أكاديمية حسوب]). إن فهم طريقة عمل قواعد البيانات العلائقية مهم جدًا لفهم [[Rails/active record|Active Record]] في ريلز بشكل عام. | ||
=== | === Active Record كإطار عمل ORM === | ||
يزوّد | يزوّد [[Rails/active record|Active Record]] بمجموعة من المهام، أهمها القابلية على: | ||
* تمثيل النماذج (models) وبياناتها. | * تمثيل النماذج (models) وبياناتها. | ||
* تمثيل العلاقات بين هذه النماذج. | * تمثيل العلاقات بين هذه النماذج. | ||
سطر 27: | سطر 28: | ||
* تنفيذ عمليات قواعد البيانات بشكل غرضي التوجه. | * تنفيذ عمليات قواعد البيانات بشكل غرضي التوجه. | ||
== العرف | == العرف فوق الضبط في Active Record == | ||
عند كتابة التطبيقات باستخدام لغات برمجة أو واجهات عمل أخرى، قد يكون من الضروري كتابة الكثير من تعليمات التهيئة والضبط الضرورية لعمل التطبيق. يعد ذلك صحيحًا من أجل واجهات عمل ORM بشكل عام. لكن إذا اتبعت العرف المتبنى من قبل ريلز، فستحتاج إلى كتابة القليل من تعليمات التهيئة (وبعض الأوقات قد لا تحتاج إلى كتابة تهيئة مطلقًا) عند إنشاء نماذج | عند كتابة التطبيقات باستخدام لغات برمجة أو واجهات عمل أخرى، قد يكون من الضروري كتابة الكثير من تعليمات التهيئة والضبط الضرورية لعمل التطبيق. يعد ذلك صحيحًا من أجل واجهات عمل ORM بشكل عام. لكن إذا اتبعت العرف المتبنى من قبل ريلز، فستحتاج إلى كتابة القليل من تعليمات التهيئة (وبعض الأوقات قد لا تحتاج إلى كتابة تهيئة مطلقًا) عند إنشاء نماذج [[Rails/active record|Active Record]]. تصب الفكرة في حال هيأت تطبيقك بالطريقة ذاتها معظم الوقت، فتلك الطريقة يجب أن تكون الطريقة الافتراضية. لذلك، ستحتاج إلى التهيئات الصريحة فقط في تلك الحالات التي لا تستطيع فيها التقيّد بالأعراف المعيارية (standard convention). | ||
=== أعراف التسمية === | === أعراف التسمية === | ||
بشكل افتراضي، يستخدم | بشكل افتراضي، يستخدم [[Rails/active record|Active Record]] بعض أعراف (اصطلاحات) التسمية للحاجة إلى الربط بين النماذج وجداول قاعدة البيانات. يجمع ريلز أسماء الأصناف لمعرفة أسماء الجداول. لذا، من أجل الصنف <code>Book</code>، يجب أن تنشئ جدولًا في قاعدة البيانات يسمّى <code>books</code>. تعد طريقة الجمع الخاصة بريلز طريقةً قويةً جدًا، والتي تمكّنك من جمع الكلمات النظامية والشاذة. عند استخدام أسماء الأصناف المكوّنة من كلمتين أو أكثر، يجب أن يراعي اسم النموذج أعراف لغة [[Ruby|روبي]]، وذلك باستخدام نمط سنام الجمل (CamelCase)، بينما يجب على أسماء الجداول أن تحوي الكلمات مفصولة بواسطة علامة الترقيم "_". أمثلة: | ||
* جدول قاعدة بيانات: جمع مع علامة ترقيم "_" تفصل الكلمات (مثال: book_clubs). | * جدول قاعدة بيانات: جمع مع علامة ترقيم "_" تفصل الكلمات (مثال: book_clubs). | ||
* صنف النموذج <code>Model</code>: مفرد مع أول حرف كبير من كل كلمة (مثال: BookClub). | * صنف النموذج <code>Model</code>: مفرد مع أول حرف كبير من كل كلمة (مثال: BookClub). | ||
سطر 55: | سطر 56: | ||
=== أعراف المخطط === | === أعراف المخطط === | ||
يستخدم | يستخدم [[Rails/active record|Active Record]] بعض أعراف التسمية من أجل الحقول في قواعد البيانات، وذلك بناءً على الهدف من هذه الحقول. | ||
* المفاتيح الأجنبية (Foreign keys): يجب على هذه الحقول أن تراعي النمط التالي "مُعرِّف_اسم_الجدول_المفرد_id" (مثال: item_id، order_id). هذه هي الحقول التي يجب على | * المفاتيح الأجنبية (Foreign keys): يجب على هذه الحقول أن تراعي النمط التالي "مُعرِّف_اسم_الجدول_المفرد_id" (مثال: item_id، order_id). هذه هي الحقول التي يجب على [[Rails/active record|Active Record]] النظر إليها عند إنشاء العلاقات بين النماذج. | ||
* المفاتيح الرئيسية (Primary keys): بشكل افتراضي، يستخدم | * المفاتيح الرئيسية (Primary keys): بشكل افتراضي، يستخدم [[Rails/active record|Active Record]] حقل العدد الصحيح المسمى id كالمفتاح الرئيسي للجدول. عند استخدام [[Rails/active record migrations|ترحيلات Active Record]] لإنشاء جداولك، سيتم إنشاء هذا الحقل تلقائيًا. | ||
هناك مجموعة من الحقول الاختيارية التي تضيف ميزات إضافية إلى كائنات | هناك مجموعة من الحقول الاختيارية التي تضيف ميزات إضافية إلى كائنات [[Rails/active record|Active Record]]: | ||
* الحقل <code>created_at</code>: يعيّن تلقائيًا تاريخ إنشاء السجل. | * الحقل <code>created_at</code>: يعيّن تلقائيًا تاريخ إنشاء السجل. | ||
* الحقل <code>updated_at</code>: يعيّن تلقائيًا تاريخ تعديل السجل. | * الحقل <code>updated_at</code>: يعيّن تلقائيًا تاريخ تعديل السجل. | ||
سطر 65: | سطر 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> سيخزّن عدد التعليقات المرتبطة بكل مقالة. | ||
'''ملاحظة''': في حين أن هذه الحقول اختيارية، فهي حقيقةً محجوزةً من قبل | '''ملاحظة''': في حين أن هذه الحقول اختيارية، فهي حقيقةً محجوزةً من قبل [[Rails/active record|Active Record]]. تجنب تسمية الحقول بأسماء محجوزة إلى في حال أردت المزيد من الفعالية. مثلًا، الكلمة <code>type</code> هي كلمة محجوزة تستخدم لوراثة الجدول الوحيد. في حال لم تكن مستخدمًا لهذه الوراثة، حاول المجيء بأسماء مختلفة مثل "context"، والتي تعبر بشكل دقيق عن البيانات التي تُنمذَج (modeling). | ||
== إنشاء نماذج | == إنشاء نماذج Active Record == | ||
من السهل جدًا إنشاء نماذج | من السهل جدًا إنشاء نماذج [[Rails/active record|Active Record]]. كل ما يتوجب عليك فعله هو إنشاء صنف فرعي يرث من الصنف <code>ApplicationRecord</code>:<syntaxhighlight lang="rails"> | ||
class Product < ApplicationRecord | class Product < ApplicationRecord | ||
end | end | ||
سطر 104: | سطر 105: | ||
== العمليات CRUD: قراءة وكتابة البيانات == | == العمليات CRUD: قراءة وكتابة البيانات == | ||
المصطلح CRUD هو اختصار لأربع عمليات مستخدمة على البيانات: إنشاء (Create)، قراءة (Read)، تحديث (Update)، وحذف (Delete). تلقائيًا، ينشئ | المصطلح CRUD هو اختصار لأربع عمليات مستخدمة على البيانات: إنشاء (Create)، قراءة (Read)، تحديث (Update)، وحذف (Delete). تلقائيًا، ينشئ [[Rails/active record|Active Record]] توابعًا لإتاحة قراء وكتابة البيانات المخزنة في قواعد البيانات. | ||
=== الإنشاء === | === الإنشاء === | ||
يمكن إنشاء كائنات | يمكن إنشاء كائنات [[Rails/active record|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"> | ||
سطر 125: | سطر 126: | ||
=== القراءة === | === القراءة === | ||
يزوّد | يزوّد [[Rails/active record|Active Record]] بواجهة برمجية غنية من أجل قراءة البيانات من قواعد البيانات. فيما يلي مجموعة من الأمثلة المختلفة حول وصول البيانات المزودة من قبل [[Rails/active record|Active Record]]:<syntaxhighlight lang="rails"> | ||
# تعيد مجموعة تحوي كل المستخدمين | # تعيد مجموعة تحوي كل المستخدمين | ||
users = User.all | users = User.all | ||
سطر 140: | سطر 141: | ||
</syntaxhighlight>يمكنك قراءة المزيد حول الاستعلامات باستخدام | </syntaxhighlight>يمكنك قراءة المزيد حول الاستعلامات باستخدام [[Rails/active record|Active Record]] في توثيق [[Rails/active record querying|واجهة استعلامات Active Record]]. | ||
=== التحديث === | === التحديث === | ||
بعد إعادة كائن | بعد إعادة كائن [[Rails/active record|Active Record]]، يمكن تعديل خاصياته ومن ثم حفظه في قاعدة البيانات:<syntaxhighlight lang="rails"> | ||
user = User.find_by(name: 'David') | user = User.find_by(name: 'David') | ||
user.name = 'Dave' | user.name = 'Dave' | ||
سطر 155: | سطر 156: | ||
=== الحذف === | === الحذف === | ||
بالمثل، عند استرجاع كائن | بالمثل، عند استرجاع كائن [[Rails/active record|Active Record]]، يمكن حذفه من قاعدة البيانات كالتالي:<syntaxhighlight lang="rails"> | ||
user = User.find_by(name: 'David') | user = User.find_by(name: 'David') | ||
user.destroy | user.destroy | ||
سطر 169: | سطر 170: | ||
== التحقق == | == التحقق == | ||
يمكنك | يمكنك [[Rails/active record|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"> | ||
سطر 180: | سطر 181: | ||
user.save # => false | user.save # => false | ||
user.save! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank | user.save! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank | ||
</syntaxhighlight>يمكنك قراءة المزيد حول هذا الموضوع في دليل [[Rails/active record validations|التحقق من صحة | </syntaxhighlight>يمكنك قراءة المزيد حول هذا الموضوع في دليل [[Rails/active record validations|التحقق من صحة Active Record]]. | ||
== توابع رد النداء (Callbacks) == | == توابع رد النداء (Callbacks) == | ||
تتيح توابع رد النداء الخاصة | تتيح توابع رد النداء الخاصة بـ [[Rails/active record|Active Record]] إمكانية ربط تعليمات معينة بأحداث مخصصة في دورة حياة النموذج. يمكّنك ذلك من إضافة السلوك لنماذجك عن طريق تنفيذ التعليمات بشكل خفي عند إطلاق هذه الأحداث، مثلًا عند إنشاء سجل جديد، أو تحديثه أو حذفه. يمكنك تعلم المزيد عن توابع رد النداء في دليل [[Rails/active record callbacks|ردود نداء Active Record]]. | ||
== التهجيرات == | == التهجيرات == | ||
يزوّد ريلز بلغة ذات نطاق لإدارة مخططات قواعد البيانات التي تدعى "بالتهجيرات" (migrations). تُخزّن التهجيرات في ملفات، وتنفّذ على قواعد البيانات التي يدعمها | يزوّد ريلز بلغة ذات نطاق لإدارة مخططات قواعد البيانات التي تدعى "بالتهجيرات" (migrations). تُخزّن التهجيرات في ملفات، وتنفّذ على قواعد البيانات التي يدعمها [[Rails/active record|Active Record]] بواسطة <code>rake</code>. في الملف التالي تهجير ينشئ جدولًا:<syntaxhighlight lang="rails"> | ||
class CreatePublications < ActiveRecord::Migration[5.0] | class CreatePublications < ActiveRecord::Migration[5.0] | ||
def change | def change | ||
سطر 204: | سطر 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 الرسمي.] |
المراجعة الحالية بتاريخ 09:16، 24 مارس 2019
هذا الدليل هو مدخل إلى المكتبة Active Record. بعد قراءة هذا الدليل، ستتعرف على:
- ما هي تقنية ORM (اختصار للعبارة Object Relational Mapping أي "ربط الكائنات العِلاقيَّة") وما هو Active Record وكيفية استعمالهما في ريلز.
- كيف ينسجم Active Record مع النموذج MVC (اختصار للعبارة Model-View-Controller).
- كيفية استعمال نماذج Active Record (أي Active Record models) لمعالجة وتعديل البيانات المخزَّنة في قاعدة بيانات عِلاقيِّة (relational database).
- اصطلاحات تسمية مخطَّط Active Record.
- مفهوم تهجيرات، وتحققات، وردود نداء قاعدة البيانات.
ما هو 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 في ريلز بشكل عام.
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
يمكنك قراءة المزيد حول هذا الموضوع في دليل التحقق من صحة Active Record.
توابع رد النداء (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.