راکت
حل شده

ارتباط چند به چند یک جدول با خودش many-to-many from the same table

5 پاسخ

سلام و درود خدمت همه ی دوستان و عزیزان راکتی
اقا من یک پروژه ای دارم که نیاز به ارتباط چند به چند یک جدول با خودشه.
برای درک نیاز این موضوع مثال برنامه اینستا رو داشته باشید که هر کار بر چندین دنبال کننده و چندین دنبال شونده داره
موضوع رو در لینکی که زیر قرار میدم میتونید بهتر ببینیدو خودش هم راهنمایی داره که من درست متوجهش نشدم.
many-to-many from the same table

حالا سناریو خودم رو توضیح میدم که چی هست صحنه که دوستان بهتر بتونن بنده رو راهنمایی کنن
من دارم برای یه رستوران غذای آماده پروژه ای مینویسم
موضوع برای غذا های این پروژه هست در زمانی که میخوام سفارشی رو ثبت کنم و موجودی اون غذا کم کنم.

قضیه اینطوریه که در غذای آمده ای مثلا شما صد پرس چلو داری ، پنجاه تا جوجه ، پنجاه تا کوبیده (فرض مسئله)
خب برای فروش سفارش ها به صورت چلو جوجه کباب و چلو کباب کوبیده هست که هم چلو توشه هم کوبیده یا جوجه
چلو یه موجودی داره و جوجه هم همینطور
جوجه به تنهایی و چلو هم به تنهایی قابل فروش هست
یعنی نمیشه بگیم فقط غذای چلو جوجه کباب داریم و چلوی تنها رو نمیدیو یا جوجه ی تنها رو نمیتونیم بدیم
پس قرار دادن موجودی برای چلو جوجه کباب بی معنی میشه چون با فروش اون باید یکی از موجودی چلو ها و یکی از موجودی جوجه ها کم بشه

حالا اینجا یک غذا (چلو جوجه کباب ) دو تا پدر (چلو و جوجه ) رو داره و چلو هم دو تا فرزند (چلو جوجه کباب و چلو کباب کوبیده ) رو داره

در کل قراره محصولی که پدری داره موجودی ای نداشته باشه و با فروش اون از موجودی تمام پدر هاش یکی کم بشه
مثلا با فروش چلو جوجه کباب از موجودی دو پدرش که چلو و جوجه هست یکی کم بشه

تنها روشی ک ب فکرم میرسه رابطه چند به چند جدول محصولاتم با خودشه
جدول محصولات (که غذا هم شاملشه) و دسته بندیمم به شکل زیره:

Schema::create('categories', function (Blueprint $table) {
    $table->id();
    $table->string('name');

});
Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name')->unique();
    $table->integer('price')->default(0);
    $table->integer('stock')->default(0);

});
Schema::create('category_product',function (Blueprint  $table){
    $table->unsignedBigInteger('category_id');
    $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
    $table->unsignedBigInteger('product_id');
    $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
    $table->primary(['category_id','product_id']);
});

بخش ثبت محصولات (غذا ها و ... )در حالت فعلی رو میتونید ببینید که هنوز این بحثی که گفتم بهش اضاف نشده و برای حساب کتاب موجودی هاش لازمه واقعا
صفحه ی محصولات

ثبت پرسش جدید

پاسخ‌ها

5
محمد رضا
محمد رضا
@salar.mohammad2013

تخصص: Full Stack Developer

بهترین پاسخ

اقا بر اساس لینکی که اول فرستادم با بررسی های خیلی بیشتر موفق به انجامش شدم
فقط کافیه یه جدول دیگه با هر نامی که دوس داری ایجاد کنی
داخل جدول جدید دو تا ستون باز هم با هر نامی که دوس دارید ایجاد میکنید و مرتبط میکنید جفتشو به عنوان کلید خارجی به کلید اصلی جدولی که میخوایید ارتباط چند به چند با خودش داشته باشه
توی مثال من parent_id و child_id کلید خارجی برای id از جدول prodcuts هستند

Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name')->unique();
    $table->integer('price')->default(0);
    $table->integer('stock')->default(0);

});

Schema::create('foods',function (Blueprint  $table){
    $table->unsignedBigInteger('parent_id');
    $table->foreign('parent_id')->references('id')->on('products')->onDelete('cascade');
    $table->unsignedBigInteger('child_id');
    $table->foreign('child_id')->references('id')->on('products')->onDelete('cascade');
    $table->primary(['parent_id','child_id']);
});

در مرحله ی اخر هم این ارتباط رو در مدل خودتون قرار میدین
نیاز نیست برای این جدول جدید مدل بسازید
من فقط در مدل product این قطعه کد پایین رو قرار دادم

    public function parents() {
        return $this->belongsToMany(Product::class, 'foods', 'child_id', 'parent_id');
    }

    public function childs() {
        return $this->belongsToMany(Product::class, 'foods', 'parent_id', 'child_id');
    }

در رابطه با طریقه ی کم کردن موجودی محصولات پدر در یک حلقه برای هر محصول قطعه کد زیر رو زدم
که به این صورت هست که اگر این محصول پدری داره بره از هر پدرش موجودی رو کم کنه اگر هم نداره فقط از خودش کم کنه

            if (Product::find($product['product_id'])->parents->count()){
                foreach (Product::find($product['product_id'])->parents as $parent){
                    DB::table('products')->where('id',$parent['id'])->decrement('stock', $product['count']);
                }

            }else{
                DB::table('products')->where('id',$product['product_id'])->decrement('stock', $product['count']);
            }

@msdabbagh
@mohaligateway

محمدسجاد دباغ
محمدسجاد دباغ
@mdabbagh

تخصص: برنامه نویس لاراول

سلام!
فکر میکنم اگر جدول غذاهای پایه ( برنج ، مرغ ، کباب و ... ) جدا باشه و یک جدول هم برای غذاهای ترکیبی ( برنج + مرغ ) ایجاد بشه بهتر باشه.
و جدول غذای ترکیبی رابطه یک به چند با جدول پایه داشته باشه و موقع سفارش غذای ترکیبی ، لیست غذای های پایه فراخوانی و کم بشه.
جدول ترکیبی میتونه هم یک عنوان بگیره تا به جای برنج و مرغ ، کاربر بنویسه چلومرغ

محمد رضا
محمد رضا
@salar.mohammad2013

تخصص: Full Stack Developer

مرسی ایده ی جالبی بود
ولی در مرحله ی اول این که چون قراره این محصولات نمایش داده بشن (تصویری که در انتها قرار دادم) انتخاب محصولات مختلف از جداول مختلف که یک ویژگی مشترک دارن همشون و بعد فهمیدن این که ایدی این محصول برای کدوم جدول و محصوله برای افزودن، حذف ، ویرایش به شدت به نظرم حجم کد رو بالا میبره و دستورات شرطی رو زیاد میکنه

برای قضیه که گفتید به جای برنج و مرغ کاربر مینویسه چلو مرغ، بله قرار نیست کاربر دوتا رو برای یک سفارش بنویسه

در تعریف محصول، کاربر میزان پرس برنج و سیخ جوجه رو که باید جدا مشخص کنه و جدا هم میتونه بفروشه پس به صورت جدا تعریف و میتونن انتخاب بشن
اما محصولی که دارای پدر هست موقع تعریف پدر هاش مشخص میشن مثلا همونطور که گفتم غذایی با اسم چلو مرغ دارای دو پدر چلو و مرغ هست

من توی دسته بندی ها هم رابطه ای که گذاشتم یک محصول میتونه چند دسته بندی داشته باشه و ب راحتی انتخاب و نمایش داده میشه
دسته بندی ها

ثبت فاکتور

شاید پاسخ شما همین‌جا باشد

moha li
moha li
@mohaligateway

تخصص: توسعه دهنده لاراول و Vue

سلام
برای اینکه دوستان بتونن بهتر به شما دوست عزیز کمک کنن اگه بتونید یک فلو چارت ارائه بدید راحت تر می شه🌹
@salar.mohammad2013

محمد رضا
محمد رضا
@salar.mohammad2013

تخصص: Full Stack Developer

ب نظرم تا جایی که تونستم کامل توضیح دادم
چیزی که نیاز هست ارتباط چند به چند یک جدول با خودشه
مثل قضیه ای که لینکش رو در ابتدای بحث قرار دادم
اگر جایی ابهام هست سوال کنید توضیح بدم
@mohaligateway

برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام