جدول المحتويات
تسمى هذه العلاقة أيضا hasMan، وتستخدم عندما نريد ربط صف في جدول معين مع صفوف أخرى في جدول أخر.
لفرض اننا نقوم ببرمجة موقع تجارة إلكترونية، ويوجد لدينا جدول brand وينتمي لهذا الـ brand مجموعة من Product هنا تسمى العلاقة One وهو brand إلى many وهو Product، مثال أخر لنفرض أنك تبرمج موقع إخباري ويوجد لكل مقال تعليقات هنا نستخدم علاقة one to many بحيث أن المقال له مجموعة من التعليقات، ومجموعة من التعليقات تنتمي لمقال واحد.
لتنفيذ علاقة one to many فإننا نحتاج إلى جدولين، هنا سوف أستخدم جدول brand بحيث ينتمي له مجموعة من products.
public function up() { Schema::create('brands', function (Blueprint $table) { $table->id('id'); $table->string('name'); $table->timestamps(); }); }
public function up() { Schema::create('products', function (Blueprint $table) { $table->id('id'); $table->forignId('brand_id')->constrained(); $table->string('name'); $table->string('slug'); $table->double('price'); $table->integer('qty'); $table->timestamps(); }); }
كما نلاحظ أنه في جدول products تم إضافة brand_id ، فهو الحقل الذي سوف يربط بين brand و product، مع العلم أن التسمية يجب أن تكون إسم الجدول الأب لكن مفرد ومن ثم ـid، لكن لو تم تغيير هذا الإسم مثلا إلى brands_id فيجب تعريف ذلك في الـ model.
في Brand Model يجب تحديد علاقتة مع Product Model من خلال إضافة دالة product وبما أن brand يحتوي على أكثر من product فيجب أن يرجع علاقة hasMany من جدول products
class Brand extends Model
{
public function products()
{
return $this->hasMany(Product::class);
}
}
لكن إذا كان forignKey أي حقل العلاقه بإسم غير brand_id مثلا إذا كان brands_id فيجب أن يتم تحديد ذلك في العلاقة، من خلال إضافة باراميتر ثاني يحتوي على إسم الحقل
public function products() { return $this->hasMany(Product::class,'brands_id'); }
كما قمنا بتعريف العلاقة hasMany في Brand Model، نستطيع أيضا تحديد العلاقة العكسية، ففي Product Model نقوم بإضافة دالة جديده بإسم brand والتي ترجع belongsTo بمعنى ينتمي إلى
class Product extends Model
{
public function brand()
{
return $this->belongsTo(Brand::class);
}
}
كذلك إذا كان تم تغيير إسم الحقل فيجب تعريف ذلك بالعلاقه كما بالمثال أعلاه.
بعد تحديد العلاقة بين الموديل، نستطيع الأن جلب البيانات
$brand = Brand::find(1); $products = $brand->products;
هذه الجملة ترجع brand بالمعرف id=1 وجميع المنتجات التي تتبع هذا brand، وبشكل مشابة نستطيع إرجاع إسم المنتج مع نوع brand وذلك من خلال العلاقة العكسية
$product = Product::find(1); $brand = $product->brand; dd($brand->name);
$brand = Brand::find(1); $product = new Product(); $product->name = 'iPhone X'; $product->slug = 'iphone-x'; $product->price = '899.99'; $product->qty = 10; $product->description = 'Some description';
// Saving related model $brand->products()->save($product);
كما نستطيع أيضا إستخدام saveMany عوضا عن إستدام save
لجلب جميع brand مع المنتجات التابعة له
$brands = Brand::select('id','name')->with('products:id,brand_id,name,price')->get(); return $brands;
[ { "id": 1, "name": "Samsung", "products": [ { "id": 3, "brand_id": 1, "name": "iPhone X", "price": 899.99 } ] }, { "id": 2, "name": "Apple", "products": [ { "id": 1, "brand_id": 2, "name": "Iphone 11", "price": 1000 }, { "id": 2, "brand_id": 2, "name": "IPhone Pro Max", "price": 1500 } ] } ]
لجلب المنتجات مع إسم البراند التابع له
$brands = Product::select('id','name','brand_id','price')->with('brand:id,name')->get(); return $brands;
[ { "id": 1, "name": "Iphone 11", "brand_id": 2, "price": 1000, "brand": { "id": 2, "name": "Apple" } }, { "id": 2, "name": "IPhone Pro Max", "brand_id": 2, "price": 1500, "brand": { "id": 2, "name": "Apple" } }, { "id": 3, "name": "iPhone X", "brand_id": 1, "price": 899.99, "brand": { "id": 1, "name": "Samsung" } } ]
إذا أردنا أن نحصل على البراند مع المنتجات التابعة لها لكن سعرها فوق 500 وأن يتم ترتيبها حسب الإسم
$brands = Brand::select('id', 'name')->with(['products' => function ($q) { $q->select('id', 'name', 'price','brand_id') ->where('price', '>', 500) ->orderBy('name', 'asc'); }])->get(); return $brands;
كما نلاحظ أنه من جدول Brand يجب أن يتم الحصول على id ومن جدول product يجب الحصول على brand_id لأنه هو الذي يربط بين الجدولين.
حذف البيانات في علاقة one to many تشبة طريقة الإدخال حيث بداية يجب الحصول على الأب وهو brand ومن ثم إستخدام العلاقة products لحذف جميع المنتجات التابعة له.
لحذف منتجات البراند بالمعرف id=1
$brand = Brand::find(1); $brand->products()->delete();
عند طلب البيانات بعلاقة تحصل عليها بهذا الشكل { \"id\": 2, \"name\": \"IPhone Pro Max\", \"brand_id\": 2, \"price\": 1500, \"brand\": { \"id\": 2, \"name\": \"Apple\" } }, هل يمكن اخلي حقول جدول البراند مثل حقول المنتج بمعنى لا يوجد غلاف باسم براند يغطيهم مثل هذا { \"id\": 2, \"name\": \"IPhone Pro Max\", \"brand_id\": 2, \"price\": 1500, \"brand_id\": 2, \"brand_name\": \"Apple\" },
كنت انتظر حديتك عن العلاقات شكرا خصوصا معقدة منها
شرح جميل كافي ووافي
السلام عليكم اخي هنالك syntax error في products migration بالضبط في ال foreignId
Mohamed Osama
شكرا ياغلى الله يوفقك ارجو ان تفتح قناه على يوتيوب والله محتواك قوى جدا من شخص محترف الرجاء كمل فى العلاقات شكرا اخى العزيز