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

لارافيل 9 : كيف استيراد المعلومات منتج باستخدام جدول ف المنتصف

سالم التوبي2

السؤال

السلام عليكم, 

اولاً فكرة مشروع هو إظهار اسعار منتجات 
عندي كم جدول :
Product, ProductPrice, Region, Wilayat, Store, Category
سويت migrationو Seeders واتوقع سويت Model

المشكلة انا سيء ف علاقات بين الجداول والبيانات
المهم سويت التالي  ل Product model

class Product extends Model
{
    use HasFactory;

    protected function category(){

        return $this->belongsTo(Category::class);
    }

    protected function productPrice(){
        return $this->belongsToMany(ProductPrice::class);
    }

كذلك مودل ProductPrice
 

class ProductPrice extends Model
{
    use HasFactory;

    public function product(){
        return $this->hasMany(Product::class)->withPivot('product_id');
    }

    public function store(){
        return $this->hasMany(Store::class);
    }

 

ف الكنترولر 
 

public function index()
    {
        $products = ProductPrice::with('Product')->get();
        return view('test', compact('products'));
    }

 

قرأت Laravel Docs وحصلت شيء اسمه Pivot بس ما فهمت له 
https://laravel.com/docs/9.x/eloquent-relationships#retrieving-intermediate-table-columns

كذلك قرأت هذي المقالة https://www.itsolutionstuff.com/post/laravel-9-many-to-many-eloquent-relationship-tutorialexample.html
 

المطلوب اطلع اسماء المنتجات واقدر اعرض سعر المنتج واي محل Store يبيعه ووين.

اعتذر على ازعاج وارفق لكم المشروع.

 ديسكورد MOGr488#4281
 

omprices.7z

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 1

لديك بعض الأخطاء في تعريف العلاقات، عندما نتحدث عن السعر فهو ينتمي لمنتج و ينتمي لمتجر:

ProductPrice:

belongsTo Product
belongsTo Store

أما عندما نتحدث عن المنتج فنقول أن المنتج لديه عدة أسعار، و موجود في عدة متاجر:

Product

hasMany ProductPrice
belongsToMany Store

أما عندما نتحدث عن المتجر فنقول أنه يبيع عدة منتجات و لديه عدة أسعار:

Store:

hasMany ProductPrice
belongsToMany Product

العلاقة بين المتجر و المنتج هي كثير لكثير و الجدول الوسيط هو product_prices.

 

توابع العلاقات نُعرفها عامة public و ليس protected، أيضاً عند تعريفك للمفاتيح الأولية لم تتبع العُرف لارافل يستخدم id و عليه يجب عليك إعادة تعريف خاصية المفتاح الأولي لكل نموذج و وضع اسم العمود، مثلا في النموذج Product:

protected $primaryKey = 'product_id';

و في النموذج Store:

protected $primaryKey = 'store_id';

و في النموذج ProductPrice:

protected $primaryKey = 'productPrice_id';

و نفس الأمر بالنسبة للبقية.

عليه عند تعريف العلاقات في النموذج ProductPrice نكتب:

public function product() {
  return $this->belongsTo(Product::class, 'product_id', 'product_id');
}

public function store() {
  return $this->belongsTo(Store::class, 'store_id', 'store_id');
}

يجب تمرير أسماء الحقول الثانوية في المعاملات (الثاني و الثالث) لأنك غيرت و لم تتبع العرف في التسمية و إن لم تمرر الأسماء الصحيحة ستحدث أخطاء.

في النموذج Product:

public function prices(){
  return $this->hasMany(ProductPrice::class, 'product_id', 'product_id');
}

public function stores()
{
  return $this->belongsToMany(Store::class, 'product_prices', 'product_id', 'store_id');
}

أما بالنسبة للنموذج Store:

public function prices(){
  return $this->hasMany(ProductPrice::class, 'store_id', 'store_id');
}

public function products()
{
  return $this->belongsToMany(Product::class, 'product_prices', 'store_id', 'product_id');
}

أخيراً في المتحكم يُمكنك جلب البيانات بالشكل الذي تريد مثلاً:

$products = Product::with('prices', 'prices.store')->get();
$stores = Store::with('prices', 'prices.product')->get();

return view('test', compact('products', 'stores'));

في ملف العرض يُمكنك الوصول للبيانات بالشكل التالي:

<h2>Products</h2>
<ol>
    @foreach($products as $product)
        <li>
            {{ $product->productName }}
            <ul>
                @foreach($product->prices as $price)
                    <li>
                        <strong>Store: </strong> {{ $price->store->storeName }} /
                        <strong>Price: </strong> {{ $price->productPrice }}
                    </li>
                @endforeach
            </ul>
        </li>
    @endforeach
</ol>


<hr>

<h2>Stores</h2>
<ol>
    @foreach($stores as $store)
        <li>
            {{ $store->storeName }}
            <ul>
                @foreach($store->prices as $price)
                    <li>
                        <strong>Product: </strong> {{ $price->product->productName }} /
                        <strong>Price: </strong> {{ $price->productPrice }}
                    </li>
                @endforeach
            </ul>
        </li>
    @endforeach
</ol>

قمت ببذر بعض البيانات و كانت النتيجة كالتالي:

pro_stores.thumb.JPG.e924c80bdb4c2a7644e64a1d7446aecb.JPG

ركزت فقط على النماذج الثلاثة Product و ProductPrice  و Store و الحالة التي ذكرتها، بقية النماذج عليك تعريف العلاقات فيها بنفس الشكل.

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 15 ساعات قال عبود سمير:

$products = Product::with('prices', 'prices.store')->get(); $stores = Store::with('prices', 'prices.product')->get();

لو سمحت ممكن تشرح ايش تسوي With() ؟

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 3 ساعات قال سالم التوبي2:

لو سمحت ممكن تشرح ايش تسوي With() ؟

تُستخدم with لتحميل العلاقات بشكل حثيث لتقليل عدد الاستعلامات و يُسمى المصطلح باللغة الإنجليزية Eager loading

يُمكنك الإطلاع على: التحميل الحثيث Eager loading لفهم المغزى من إستخدام with، و الهدف كما قلت هو معالجة مشكلة (N+1) خصوصاً عند الوصول للعلاقة على شكل خاصية في الحلقات

يوجد في الرابط أعلاه مثال لنموذج الكتاب (Book) و نموذج الكاتب (Author) و العلاقة واحد لكثير.

عند جلب كافة الكتب ثم في الحلقة نصل لإسم الكاتب عبر العلاقة بالشكل التالي:

$books = Book::all();

foreach ($books as $book) {
   echo $book->author->name;
}

ذلك يعني إستعلام واحد لجلب كافة الكتب، ثم في الحلقة من أجل كل كتاب إستعلام إضافي لجلب الكاتب. و هذا النوع من التحميل يُسمى التحميل الكسول و هنا مُشكلة الإستعلامات  (N + 1)، أما بإستخدام with نقوم بتحميل العلاقة بشكل مُسبق مع الإستعلام الأولي. ( أي إستعلام لجلب كافة الكتب و إستعلام واحد فقط إضافي لجلب الكُتاب)

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

جزاك الله خير اخوي عبود سمير,

للناس الي فالمستقبل تقرأ هذا السؤال, هنا بعض اشياء فادتني:
علاقة Many to Many

علاقة Many to Many من Laravel 9 Docs

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...