لارافيل, Model / 2024-05-14

ما هي العلاقة Polymorphic Many في لارافيل

ما هي العلاقة Polymorphic Many في لارافيل

2024-05-14 وقت القراءه : 6 دقائق

تحدثنا في مقال سابق عن العلاقة Polymorphic في لارافيل، وكيفية عمل جدول واحد للتعليقات لمجموعة من الجداول، في هذا المقال سوف نتحدث عن علاقة Polymorphic Many.

 

ما هي العلاقة Polymorphic Many.

لفرض ان لدينا الجداول التالية

Articles
            Id
            Name
 
Videos
            Id
            Name
 
Products
            Id
            Name
 
Tags
            Id
            Name

ولكن لدينا كل ( مقال، فيديو، منتج) يحتوي على مجموعة من التعليقات، وكل تعليق ينتمي لأكثر من ( فيديو، مقال، منتج).

أي أن العلاقة many to many polymorphic.

 

 

إنشاء جدول للعلاقة Polymorphic

بما أننا نتعامل مع جدول Tags هنا نحتاج لإنشاء جدول جديد باسم tagables، ولو كنا نتعامل مع جدول videos فإن إسم الجدول الجديد سيكون videoables... وهكذا

public function up()
{
    Schema::create('tagables', function (Blueprint $table) {
        $table->foreignId('tag_id')->constrained();
        $table->morphs('tagable');
        $table->timestamps();
    });
}

توضيح

النوع morphs(tagable) ستقوم بإنشاء حقلين وهما:

  • tagable_type: وبه يتم تحديد مسار الموديل التابع له التعليق.
  • tagable_id : وبه يتم تحديد id المقال، أو id الفيديو ، أو id المنتج.

 

تم وضع الإسم tagable في النوع morphs لأن إسم الجدول هو tagables ، ولو كان إسم الجدول videoables فإن إسم النوع morphs يجب أن يكون videoable ، أي أن إسم العلاقة يجب أن يكون singular.


إنشاء العلاقات في علاقة Polymorphic Many

بالطبع نحتاج لبناء العلاقات في الـ Model (Article, Video, Product)، وكذلك بناء العلاقات في الـ Model Tag.

الموديل Tag

في الموديل tag نحتاج لبناء علاقة لجميع الـ model الأخرى (Article, Video, Product)

class Tag extends Model
{
    use HasFactory;
 
    protected $fillable = ['tag_id'];
 
    public function articles()
    {
        return $this->morphedByMany(Article::class,'tagable');
    }
 
    public function videos()
    {
        return $this->morphedByMany(Video::class,'tagable');
    }
 
    public function projects()
    {
        return $this->morphedByMany(Project::class,'tagable');
    }
}

توضيح

نوع العلاقة يجب أن يكون morphByMany ومن ثم إسم الموديل، ومن ثم tagable لأننا نتعامل مع الجدول tags، فلو كنا نتعامل مع جدول videos فإنها يجب أن تكون videoable.

 

أما الموديل الأخرى 

class Video extends Model
{
    use HasFactory;
 
    public function tags()
    {
        return $this->morphToMany(Tag::class,'tagable');
    }
}
 
class Article extends Model
{
    use HasFactory;
 
    public function tags()
    {
        return $this->morphToMany(Tag::class,'tagable');
    }
}
 
class Product extends Model
{
    use HasFactory;
 
    public function tags()
    {
        return $this->morphToMany(Tag::class,'tagable');
    }
}

 

توضيح

في الموديل Product, Video, Article)، كما نرى أن إسم الدالة هي tags في جميع الموديل، نوع العلاقة morphToMany، ومن ثم tagable.

 

إدخال البيانات في علاقة Polymorphic Many

لفرض أننا لدينا فورم لإدخال المقالات، حيث يمكن كتابة عنوان المقال ، وإختيار مجموعة من الوسوم لهذا المقال

<form method="POST" action="{{ route('articles.store') }}">
    @csrf
    <input type="text" name="name" class="form-control">
    <select name="tag_id[]" multiple class="form-control">
        @foreach($tags as $tag)
            <option value="{{ $tag->id }}">{{ $tag->tag_name }}</option>
        @endforeach
    </select>
     <button type="submit" class="btn btn-primary">Submit</button>
</form>

 

لإدخال البيانات في Article Controller في الدالة Store

public function store(Request $request)
{
    $article= new Article();
    $article->name = $request->name;
    $article->save();
    $article->tags()->attach($request->tag_id);
}

 

توضيح

  • بداية تم حفظ المقال
  • إستخدام العلاقة tags ومن ثم إستخدام الدالة attach لحفظ tag_id في جدول tagables، حيث بشكل تلقائي يتم تخزين :
    • tag_id : وهو id الـ tag من جدول tags.
    • Tagable_type : وبه يتم تخزين مسار الموديل، في حالتنا هذا بما إننا قمنا بإدخال مقال سيتم إدخال App\Models\Article.
    • Tagable_id : وبه يتم تخزين id المقال.

 

ممكن الإطلاع على الصوره بالأعلى.

 

عرض البيانات في علاقة Polymorphic Many

لفرض إننا نريد عرض مقال معين مع الوسوم التابعة له

public function show($id)
{
    $article=Article::with('tags')->findOrFail($id);
    return view('article_details', compact('article'));
}

كما نلاحظ أن كل ما علينا هو إستخدام with مع إسم الدالة التي بها العلاقة وهي tags.

 

 

إضافة تعليق
Loading...