0Pricing
Ruby Academy · درس

الارتباطات

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 comments

has_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.count

has_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 يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. أساسيات Active Record
  2. عمليات الترحيل
  3. الارتباطات
  4. التحققات والاستعلامات
← العودة إلى Ruby Academy