الارتباطات
has_many وbelongs_to
الارتباطات درس مجاني في Ruby Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Ruby Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Ruby Academy 4 دروس في المجموع.
ما هي الارتباطات؟
تعلن الارتباطات العلاقات بين النماذج، بحيث يستطيع Active Record التنقل بين الصفوف المرتبطة نيابةً عنك. وبدلًا من كتابة SQL للربط، تستدعي أساليب مثل user.posts.
- تعكس الارتباطات المفاتيح الخارجية في قاعدة البيانات.
- تنشئ أساليب مساعدة تلقائيًا.
- تجعل الشيفرة مقروءة كما لو كانت تصف مجال التطبيق.
belongs_to
يشير belongs_to إلى أن هذا النموذج يحتوي على مفتاح خارجي يشير إلى نموذج آخر. فمثلًا، يحتوي Comment المرتبط بـ Post على العمود post_id.
class Comment < ApplicationRecord
belongs_to :post
end
# comment.post returns the parent Post
# Requires a post_id column on commentshas_many
يمثل has_many الجانب الآخر: إذ يمتلك سجل واحد عدة سجلات من نوع آخر. فمثلًا، يحتوي Post على عدة سجلات من نوع Comment. ويوجد المفتاح الخارجي في جانب السجلات المتعددة.
class Post < ApplicationRecord
has_many :comments
end
# post.comments returns all related comments
# post.comments.create(body: "Nice!")موضع المفتاح الخارجي
يحتوي النموذج الذي يستخدم belongs_to على المفتاح الخارجي. ففي حالة Post وComment، يحتوي جدول comments على post_id. أعدّ هذا الإعداد في عملية ترحيل باستخدام t.references :post أو add_reference.
create_table :comments do |t|
t.references :post, foreign_key: true
t.text :body
t.timestamps
endالأساليب التي يتم إنشاؤها تلقائيًا
يوفّر لك has_many :comments مجموعةً تتضمن أساليب مفيدة:
post.commentsللقراءة.post.comments.create(...)لإضافة سجل مرتبط.post.comments.countللعد.post.comment_idsلجلب المعرّفات.
post = Post.find(1)
post.comments.create(body: "First!")
puts post.comments.counthas_one
يمثل has_one ارتباطًا واحدًا بواحد، مثل User لديه Profile واحد. ويظل المفتاح الخارجي موجودًا في النموذج الآخر، وهو profiles.user_id.
class User < ApplicationRecord
has_one :profile
end
class Profile < ApplicationRecord
belongs_to :user
endعلاقة متعدد إلى متعدد باستخدام through
لإنشاء علاقة متعدد إلى متعدد، استخدم نموذج ربط وhas_many through. فمثلًا، يحتوي Student على عدة سجلات من نوع Course من خلال صفوف Enrollment.
class Student < ApplicationRecord
has_many :enrollments
has_many :courses, through: :enrollments
end
class Enrollment < ApplicationRecord
belongs_to :student
belongs_to :course
endخيارات dependent
حدّد ما يحدث للسجلات التابعة عند حذف السجل الأب باستخدام dependent:
dependent: :destroyيحذف السجلات التابعة أيضًا.dependent: :nullifyيمسح مفاتيحها الخارجية.dependent: :restrict_with_errorيمنع الحذف.
class Post < ApplicationRecord
has_many :comments, dependent: :destroy
endمشكلة الاستعلامات N+1
قد يؤدي تكرار السجلات والوصول إلى ارتباط داخل الحلقة إلى تنفيذ استعلام واحد لكل سجل، وهي مشكلة N+1 المخيفة. فقد يؤدي تحميل 10 منشورات ثم تعليقاتها إلى تنفيذ 11 استعلامًا بدلًا من استعلامين.
ويؤدي ذلك إلى إبطاء التطبيقات تدريجيًا من دون ملاحظة مع ازدياد البيانات.
# N+1: one query per post for comments
Post.all.each do |post|
puts post.comments.count
endإصلاح N+1 باستخدام includes
يخبر includes Active Record بتحميل الارتباط مسبقًا في استعلامين تقريبًا بدلًا من عدد كبير من الاستعلامات. وهذا هو الإصلاح المعتاد لمشكلة N+1.
Post.includes(:comments).each do |post|
puts post.comments.count
endأسماء مخصصة باستخدام class_name
عندما لا يتطابق اسم الارتباط مع النموذج، استخدم خيارات مثل class_name وforeign_key. فمثلًا، يمكنك إنشاء ارتباط باسم author يستند إلى نموذج User.
class Post < ApplicationRecord
belongs_to :author, class_name: "User"
endتحقق سريع
اختبر مدى فهمك للارتباطات.
مراجعة: الارتباطات
لقد تعلمت كيفية ربط النماذج:
- يحتوي
belongs_toعلى المفتاح الخارجي، بينما يمثلhas_manyوhas_oneالجانب الآخر. - يمثل
has_many throughالعلاقات من نوع متعدد إلى متعدد. - يتحكم
dependentفي عمليات الحذف المتسلسل. - تجنّب استعلامات N+1 باستخدام
includes.
بعد ذلك سنضمن سلامة البيانات باستخدام عمليات التحقق ونتعلم كيفية إجراء الاستعلامات.
الأسئلة الشائعة
هل درس «الارتباطات» مجاني؟
نعم — نص درس «الارتباطات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Ruby Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Ruby Academy 4 دروس في المجموع.
ماذا ستتعلم في «الارتباطات»؟
has_many وbelongs_to تتمرن على Ruby Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Ruby Academy؟
لا تُشترط خبرة سابقة. Ruby Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «الارتباطات»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Ruby Academy هذا؟
نعم. كل درس في Ruby Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.