اذهب إلى المحتوى

السؤال

نشر

لدي بنية هرمية في قاعدة البيانات لمشروعي، بحيث يكون لكل حساب مستخدم حساب أب أو حساب ابن بشكل بنية هرمية متعددة المستويات.

فقمت بإنشاء المودل بالشكل التالي:

public function immediateChildAccounts()
{
    return $this->hasMany('Account', 'acount_parent', 'act_id');
}

public function parentAccount()
{
    return $this->belongsTo('Account', 'acount_parent', 'act_id');
}

وعندما أريد استعادة جميع سجلات الحسابات الأبناء لحساب معيّن أقوم بالتالي:

public function allChildAccounts()
{
    $childAccounts = $this->immediateChildAccounts;
    if (empty($childAccounts))
        return $childAccounts;

    foreach ($childAccounts as $child)
    {
        $child->load('immediateChildAccounts');
        $childAccounts = $childAccounts->merge($child->allChildAccounts());
    }

    return $childAccounts;
}

ولكن مع ازدياد حجم البيانات لا أعلم إن كانت هذه الطريقة فعّالة في التعامل مع البنية الهرمية في لارافيل، حيث سأقوم بالمستقبل باستعادة جميع الحسابات الأبناء لحساب معيّن وأيضاً جميع أبنائهم وهكذا. كالتالي:

A->immediateChildAccounts() --> يجب أن أحصل على {B, C}

A->allChildAccounts() --> يجب أن أحصل على {B, D, C, E, F}

كما وأرغب أيضاً في استعادة جميع الحسابات التي ليس لها أبناء متصلة. ما هي الطريقة الأفضل لمعالجة هذه الأمور؟

Recommended Posts

  • 0
نشر

هذه هي الطريقة التي يمكنك بها استخدام recursive relations:

public function childrenAccounts()
{
    return $this->hasMany('Account', 'act_parent', 'act_id');
}

public function allChildrenAccounts()
{
    return $this->childrenAccounts()->with('allChildrenAccounts');
}

ثم يمكن استخدامها بهذا الشكل:

$account = Account::with('allChildrenAccounts')->first();

$account->allChildrenAccounts; 

$account->allChildrenAccounts->first()->allChildrenAccounts; 

بهذه الطريقة يمكنك حفظ الكثير من queries. سيؤدي هذا إلى تنفيذ استعلام واحد لكل مستوى متداخل + استعلام إضافي واحد. 

public function scopeChildless($q)
{
   $q->has('childrenAccounts', '=', 0);
}
$childlessAccounts = Account::childless()->get();

 

  • 0
نشر

يمكنك استخدام Recursive كالآتي:

public function childrenAccounts()
{
    return $this->hasMany('Account', 'act_parent', 'act_id');
}

public function allChildrenAccounts()
{
    return $this->childrenAccounts()->with('allChildrenAccounts');
}

واستدعاء الأبناء هكذا:

$account = Account::with('allChildrenAccounts')->first();

$account->allChildrenAccounts; 

$account->allChildrenAccounts->first()->allChildrenAccounts;

 

ولاستدعاء الحسابات التي لا تحتوي على أبناء, فنقوم بإضافة الدالة الآتية

public function scopeChildless($q)
{
   $q->has('childrenAccounts', '=', 0);
}

وعملية الاستدعاء تكون كالتالي

$childlessAccounts = Account::childless()->get();

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...