احمد
3 سال پیش توسط احمد مطرح شد
26 پاسخ

ذخیره شدن هر رنگ تو یک ردیف در جدول واسط order-product

سلام. خوب اول از همه برای درک بهتر از سوالم یه توضیحاتی بدم. من به این شکل عمل کردم که تو متد payment میاد و id محصول و quantity و colorid از Cart میگره و توسط متد mapWithKeys پیمایش میشن و در نهایت در جدول orderproduct ذخیره میشن. و وقتی دوتا محصول متفاوت به سبد خرید اضافه و پرداخت میشه به ازایه هر محصول میاد و یک سطر جدیدکه شامل(quantity و productid و colorid و orderid ) در جدول orderproduct اضافه میکنه. خوب تا این جا مشکلی نیست و اکی هست. اما وقتی از یک محصول دو تا رنگ متفاوت به سبد خرید اضافه می کنم و پرداخت می کنم تو جدول orderproduct یک ردیف ثبت میشه در صورتی که دوتا رنگ متفاوت از یک محصول انتخاب شده. حالا میخام در جدول orderproduct به ازایه هر color متفاوت یک ردیف در جدول ثبت بشه تا مشخص بشه که کاربر از یک محصول کدوم رنگ هارو سفارش داده.
امید وارم منظورمو درست رسونده باشم.
اینم کد من:

public function payment()
    {

        $post = Post::find(session('post_id'));
        $cart = Cart::all();

        if($cart->count()){

             $price = $cart->sum(function($cart) {

                return $cart['discount_percent'] == 0
                ? $cart['price'] * $cart['quantity']
                : ($cart['price'] - ($cart['price'] * $cart['discount_percent'] )) * $cart['quantity'];

            });

            $total_price = $price + $post->price;

            $color = $cart->pluck('color');

            $orderItems = $cart->mapWithKeys(function($cart)  {

                return [

                    $cart['product']->id => [ 'quantity' => $cart['quantity'], 'color_id' => $cart['color']] 

                ];
             });

             //dd($color);

             $order = auth()->user()->orders()->create([
                'status' => 'unpaid',
                'price' => $total_price,
                'shipping_id' => session('shipping_id')
            ]);

            $order->products()->attach($orderItems);

خوب به عنوان قدم اول من اومدم و توسط متد pluck ای دی رنگ هایی که برای هر محصول در سبد خرید ثبت شده برگردوندم. اما نمیدونم چجوری این id رنگ هارو به متد mapWithKeys اضافه کنم که اگر id محصولات هم یکی بود بر اساس رنگ بیاد و سطر جدید در جدول ایجاد کنه.
اینم خروجی $color = $cart->pluck('color');

Illuminate\Support\Collection {#1437 ▼
  #items: array:2 [▼
    0 => "2"
    1 => "3"
  ]
}

ثبت پرسش جدید
محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 3 سال پیش مطرح شد
0

اینجا نیازی به mapwithkey وجود نداره تا جایی که میبینم ولی کد زیر رو تست کن و خروجی بعد orderitem رو ببین

        $orderItems = $cart->mapWithKeys(function($cart)  {

            return [

                 $cart['id'] => ['product_id'=>$cart['product']->id,'quantity' => $cart['quantity'], 'color_id' => $cart['color']]

            ];
        });

در مرحله ی بعد به جاش کد زیر رو بنویس و خروجیش رو بگیر

        $orderItems=[];
        foreach ($cart as $item){
            $orderItems[]=[
                'product_id'=>$item['product']->id,
                'color_id'=>$item['color'],
                'quantity'=>$item['quantity']
            ];
        }

در هر دو حالت ثبت رو هم تست کن ببین کار میکنه برات یا نه


سیدعلی موسوی
تخصص : سی شارپ و پی اچ پی
@juza66 3 سال پیش آپدیت شد
0

بجای متد mapWithKeys بیای از map استفاده کنی و خودت شرط ها رو توش بنویسی بهتر نیست؟!
مثلا به جای متد mapWithKeys

$orderItems = $cart->mapWithKeys(function($cart)  {

                return [

                    $cart['product']->id => [ 'quantity' => $cart['quantity'], 'color_id' => $cart['color']] 

                ];
             });

بیایی از متد map استفاده کنی!

$orderItems = $cart->map(function($item, $key) {
   return $item;
});

البته من زیاد توی ساخت فروشگاه حرفه ای نیستم


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 3 سال پیش مطرح شد
0

سلام
از $orderItems قبل از attach شدن لطفا dd بگیر اطلاعاتش ببینیم و
جدول order_product رو هم از همون migration یا phpmyadmin یه عکس بده که فیلد هاش ببینیم بی زحمت اگر موردی نیست.

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

یعنی شما داده ای که attach میکنی خودش جدا جدا نیست برای همین attach تشخیص نمیده اونو


احمد
@ahmad316948 3 سال پیش آپدیت شد
0

@salar.mohammad2013
سلام بفرمائید اینم خروجی $orderItems

Illuminate\Support\Collection {#1450 ▼
  #items: array:1 [▼
    112 => array:2 [▼
      "quantity" => 1
      "color_id" => "2"
    ]
  ]
}

اینم مایگریشن جدول orderproduct :

 Schema::create('order_product', function(Blueprint $table) {
            $table->unsignedBigInteger('product_id');
            $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');

            $table->unsignedBigInteger('order_id');
            $table->foreign('order_id')->references('id')->on('orders')->onDelete('cascade');

            $table->integer('quantity');
            $table->bigInteger('color_id');

            $table->primary(['order_id','product_id']);
        });

جالبه در اون خروجی $orderItems که فرستام فقط یک محصول وجود داره درحالی که من دوتا محصول مشابه اما با رنگ متفاوت به سبد خرید اضافه کردم ولی فقط یک محصول رو در خروجی نمایش داده .
اما وقتی بجای mapWithKeys از map استفاده می کنم هردو محصول یکسان که رنگ متفاوتی دارند رو نمایش میده به این شکل:

Illuminate\Support\Collection {#1450 ▼
  #items: array:2 [▼
    "ilNeOAZORW" => array:1 [▼
      112 => array:2 [▼
        "quantity" => 1
        "color_id" => "3"
      ]
    ]
    "m2GqTF48g7" => array:1 [▼
      112 => array:2 [▼
        "quantity" => 1
        "color_id" => "2"
      ]
    ]
  ]
}

احمد
@ahmad316948 3 سال پیش مطرح شد
0

@juza66
سلام. ببینید متد map فقط value هارو تقییر میده نه key اما متد mapWithKeys هم value و هم key رو تقییر میده. خروجی هریک از این متدها با یک داده یکسان:
mapWithKeys :

Illuminate\Support\Collection {#1450 ▼
  #items: array:1 [▼
    112 => array:2 [▼
      "quantity" => 1
      "color_id" => "2"
    ]
  ]
}

خروجی متد map:

Illuminate\Support\Collection {#1450 ▼
  #items: array:2 [▼
    "ilNeOAZORW" => array:1 [▼
      112 => array:2 [▼
        "quantity" => 1
        "color_id" => "3"
      ]
    ]
    "m2GqTF48g7" => array:1 [▼
      112 => array:2 [▼
        "quantity" => 1
        "color_id" => "2"
      ]
    ]
  ]
}

محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 3 سال پیش آپدیت شد
0

مشکل اینه که میایی $cart['product']->id به عنوان کاید ارایه استفاده میکنی و باعث over write میشه و یک محصول روی محصول دیگه قرار میگیره چون کلید یکسانی داری

سوال قبلی هم ک مطرح کردی اگر خاطرت باشه ایدی رنگ به صورت کلید بود
ارایه رو فتم تغییر بده از داخل ویو و ارسالیت بشه colorid
اینجام همون اشتباهه
توی جدول orderproduct داری productid ذخیره میکنی
خروجی که داری نشون میدی نداره چیزی ب اسم productid چطور تشخیص بده سیستم؟؟
توی ذخیرت میای میگی auth()->user()->orders()->create باعث میشه ایدی سفارش رو سیستم بفهمه یعنی orderid رو
دو مقدار داره هر ارایت
کلید مهم نیست

Illuminate\Support\Collection {#1450 ▼
  #items: array:2 [▼
    "ilNeOAZORW" => array:1 [▼
      112 => array:2 [▼
        "quantity" => 1
        "color_id" => "3"
      ]
    ]
    "m2GqTF48g7" => array:1 [▼
      112 => array:2 [▼
        "quantity" => 1
        "color_id" => "2"
      ]
    ]
  ]
}

همین خروجی رو فقط کاری کن کلید ارایه بیاد داخلش کنار quantity و colorid چیزی به اسم productid داشته باش
مشکل حل میشه احتمال زیاد


احمد
@ahmad316948 3 سال پیش آپدیت شد
0

@salar.mohammad2013
ببینید این کد به درستی زمانیکه دوتا محصول متفاوت به سبد خرید اضافه بشه کار میکنه، فقط الان مشکل سر ذخیره کردن رنگ محصول در یک سطر جدا هست.

نقل قول خروجی که داری نشون میدی نداره چیزی ب اسم productid چطور تشخیص بده سیستم؟؟

Illuminate\Support\Collection {#1450 ▼
  #items: array:1 [▼
    112 => array:2 [▼ // اینم id محصول
      "quantity" => 1
      "color_id" => "2"
    ]
  ]
}

محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 3 سال پیش مطرح شد
0

میدونم احمد جان که اون ایدی محصولته گفتم به عنوان کلید استفاده کردی و قابل تشخیص نیست
از کجا بدونه 112 چی هست؟ جایی نوشتی مگه؟
گفتم ایدی رو بیار داخل آرایه کنار رنگ و تعداد

array:2 [
  0 => array:3 [
    "product_id" => 112
    "quantity" => 1
    "color_id" => 2
  ]
  1 => array:3 [
    "product_id" => 112
    "quantity" => 1
    "color_id" => 3
  ]
]

یعنی چیزی که ذخیره میشه این داده باشه که الان دیدی

الان مقدار orderItem رو به صورت دستی مقدار میدم قبل از attach قرار بده تا داده ی مناسب داشته باشه
کد رو تست کن ببین با این داده دو ردیف ذخیره میشه یا بازم مشکل داره
فقط همین ارایه رو اضاف کن که داده عوض شه همین

        $orderItems=[
            ['product_id'=>112,'quantity'=>1,'color_id'=>2],
            ['product_id'=>112,'quantity'=>1,'color_id'=>3]
        ];

اینو بعد از ثبت order و قبل از attach بزار و ببین چی ذخیره میشه


احمد
@ahmad316948 3 سال پیش مطرح شد
0

@salar.mohammad2013
سلام روشی که گفتید رو امتحان کردم ولی اررو داد:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '37-112' for key 'PRIMARY' (SQL: insert into `order_product` (`color_id`, `order_id`, `product_id`, `quantity`) values (2, 37, 112, 1), (3, 37, 112, 1))

اینم کد:

 $orderItems=[
                ['product_id'=>112,'quantity'=>1,'color_id'=>2],
                ['product_id'=>112,'quantity'=>1,'color_id'=>3]
            ];

          //  foreach($orderItems as $orders) {

            //    $items = $orders;
           // }

           // dd($items);

            $order->products()->attach($orderItems);

حتی مقدار $orderItems رو داخل حلقه ریختم بازم خطا داد :

SQLSTATE[HY000]: General error: 1364 Field 'quantity' doesn't have a default value (SQL: insert into `order_product` (`order_id`, `product_id`) values (38, 112), (38, 1), (38, 3))

میگه مقدار quantity نمیتونه خلی باشه


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 3 سال پیش مطرح شد
0

خطا برای اینه که داری attach میکنی و قبلا یک فیلد اضافه شده duplicate نوشته
جدول order_product رو برو داده هاشو به صورت دستی پاک کن
یا اینکه به جای atach از sync استفاده کن


احمد
@ahmad316948 3 سال پیش مطرح شد
0

@salar.mohammad2013
رفتم هم داده هارو پاک کردم و هم از sync استفاده کردم ولی بازم خطا میده:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '43-112' for key 'PRIMARY' (SQL: insert into order_product (color_id, order_id, product_id, quantity) values (3, 43, 112, 1))


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 3 سال پیش آپدیت شد
0

اها داخل migration هم باید تغییر ایجاد کنی چون کلید اصلی شماره سفارش و شماره محصوله در حالت فعلی برا همین ارور میده

 $table->primary(['order_id','product_id'],['color_id']);

php artisan migrate:fresh باید بشه که همه داده هات پاک میشه و باز ایدی محصولاتت و اینا عوض میشه


احمد
@ahmad316948 3 سال پیش مطرح شد
0

@salar.mohammad2013
الان همون تغیری که فرستادین رو در مایگریشن اعمال کنم؟


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 3 سال پیش مطرح شد
0

تغییر رو که ایجاد میکنی دیتابیست باید تغییر کنه و نیاز به اینه که رول بک کنی یا فرش کنی که اعمال بشه تغییر بر روی دیتابیس
فقط فیلد color_id رو اضاف کردم برای کلید اصلیت


احمد
@ahmad316948 3 سال پیش مطرح شد
0

@salar.mohammad2013
فکر می کن مدرست اضافه نکردین چون به ارور خوردم

Migrating: 2021_04_09_203254_create_orders_table

   ErrorException 

  stripos() expects parameter 1 to be string, array given

  at C:\xampp\htdocs\shop_mobile\vendor\laravel\framework\src\Illuminate\Database\Grammar.php:61
    57| 
    58|         // If the value being wrapped has a column alias we will need to separate out
    59|         // the pieces so we can wrap each of the segments of the expression on its
    60|         // own, and then join these both back together using the "as" connector.
  > 61|         if (stripos($value, ' as ') !== false) {
    62|             return $this->wrapAliasedValue($value, $prefixAlias);
    63|         }
    64| 
    65|         return $this->wrapSegments(explode('.', $value));

  1   C:\xampp\htdocs\shop_mobile\vendor\laravel\framework\src\Illuminate\Database\Grammar.php:61
      stripos(" as ")

  2   C:\xampp\htdocs\shop_mobile\vendor\laravel\framework\src\Illuminate\Database\Schema\Grammars\Grammar.php:230
      Illuminate\Database\Grammar::wrap()

به این شکل باید باشه:


            $table->primary(['order_id','product_id','color_id']);

محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 3 سال پیش مطرح شد
0

اره اشتباه از من بود ببخشید
همین که فرستادی خودت درستشه


احمد
@ahmad316948 3 سال پیش آپدیت شد
0

@salar.mohammad2013
سلام تست کردم جواب داد. به این شکل :

  $orderItems=[
                ['product_id'=>1,'quantity'=>1,'color_id'=>2],
                ['product_id'=>1,'quantity'=>1,'color_id'=>3]
            ];

            $order->products()->attach($orderItems);

حالا باید با متد map این لیست رو پیمایش کنم؟


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 3 سال پیش مطرح شد
0

دیگه داداش مشکل مشخص شد
چیزی که ذخیره میکنی مشکل داشت آرایه ای که میدی به attach
خروجی مناسب نشونت دادم
باید خروجی بگیری تغییر ایجاد کنی تا به این نتیجه برسی
اشتباه نکنم کافیه فقط متد mapwith key رو تغییر بدی

        $orderItems = $cart->mapWithKeys(function($cart)  {

            return [

                  ['product_id'=>$cart['product']->id, 'quantity' => $cart['quantity'], 'color_id' => $cart['color']]

            ];
        });

ورودی هاتو ببین خروجی هاتو ببین داده رو مثل چیزی که الان تست گرفتی ذخیره کن برای خودت توی یک آرایه و بعد درج کن توی دیتا بیس


احمد
@ahmad316948 3 سال پیش مطرح شد
0

@salar.mohammad2013
با متد mapWithKeys تست کردم بازم مثل قبل از یک محصول که دوتا رنگ مختلف داره فقط یک سطر در جدول order_product ثبت میشه.


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 3 سال پیش مطرح شد
0

در کل شما باید خروجی بعد متد رو بررسی کنید که order_item در فرمت مناسب باشه مهم اینه


احمد
@ahmad316948 3 سال پیش مطرح شد
0

@salar.mohammad2013
آره باید سایر متد های کالکشن رو بررسی کنم


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

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