سلام. خوب اول از همه برای درک بهتر از سوالم یه توضیحاتی بدم. من به این شکل عمل کردم که تو متد 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"
]
}
اینجا نیازی به 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']
];
}
در هر دو حالت ثبت رو هم تست کن ببین کار میکنه برات یا نه
بجای متد 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;
});
البته من زیاد توی ساخت فروشگاه حرفه ای نیستم
سلام
از $orderItems قبل از attach شدن لطفا dd بگیر اطلاعاتش ببینیم و
جدول order_product رو هم از همون migration یا phpmyadmin یه عکس بده که فیلد هاش ببینیم بی زحمت اگر موردی نیست.
90 درصد حدس میزنم orderitem برای محصول با دو رنگ رنگ ها رو ایدیش رو به صورت ارایه برای یک سطر ذخیره کرده و خودش دو سطر نیست مثلا
یعنی شما داده ای که attach میکنی خودش جدا جدا نیست برای همین attach تشخیص نمیده اونو
@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"
]
]
]
}
@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"
]
]
]
}
مشکل اینه که میایی $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 داشته باش
مشکل حل میشه احتمال زیاد
@salar.mohammad2013
ببینید این کد به درستی زمانیکه دوتا محصول متفاوت به سبد خرید اضافه بشه کار میکنه، فقط الان مشکل سر ذخیره کردن رنگ محصول در یک سطر جدا هست.
نقل قول خروجی که داری نشون میدی نداره چیزی ب اسم productid چطور تشخیص بده سیستم؟؟
Illuminate\Support\Collection {#1450 ▼
#items: array:1 [▼
112 => array:2 [▼ // اینم id محصول
"quantity" => 1
"color_id" => "2"
]
]
}
میدونم احمد جان که اون ایدی محصولته گفتم به عنوان کلید استفاده کردی و قابل تشخیص نیست
از کجا بدونه 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 بزار و ببین چی ذخیره میشه
@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 نمیتونه خلی باشه
خطا برای اینه که داری attach میکنی و قبلا یک فیلد اضافه شده duplicate نوشته
جدول order_product رو برو داده هاشو به صورت دستی پاک کن
یا اینکه به جای atach از sync استفاده کن
@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))
اها داخل migration هم باید تغییر ایجاد کنی چون کلید اصلی شماره سفارش و شماره محصوله در حالت فعلی برا همین ارور میده
$table->primary(['order_id','product_id'],['color_id']);
php artisan migrate:fresh باید بشه که همه داده هات پاک میشه و باز ایدی محصولاتت و اینا عوض میشه
تغییر رو که ایجاد میکنی دیتابیست باید تغییر کنه و نیاز به اینه که رول بک کنی یا فرش کنی که اعمال بشه تغییر بر روی دیتابیس
فقط فیلد color_id رو اضاف کردم برای کلید اصلیت
@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']);
@salar.mohammad2013
سلام تست کردم جواب داد. به این شکل :
$orderItems=[
['product_id'=>1,'quantity'=>1,'color_id'=>2],
['product_id'=>1,'quantity'=>1,'color_id'=>3]
];
$order->products()->attach($orderItems);
حالا باید با متد map این لیست رو پیمایش کنم؟
دیگه داداش مشکل مشخص شد
چیزی که ذخیره میکنی مشکل داشت آرایه ای که میدی به attach
خروجی مناسب نشونت دادم
باید خروجی بگیری تغییر ایجاد کنی تا به این نتیجه برسی
اشتباه نکنم کافیه فقط متد mapwith key رو تغییر بدی
$orderItems = $cart->mapWithKeys(function($cart) {
return [
['product_id'=>$cart['product']->id, 'quantity' => $cart['quantity'], 'color_id' => $cart['color']]
];
});
ورودی هاتو ببین خروجی هاتو ببین داده رو مثل چیزی که الان تست گرفتی ذخیره کن برای خودت توی یک آرایه و بعد درج کن توی دیتا بیس
@salar.mohammad2013
با متد mapWithKeys تست کردم بازم مثل قبل از یک محصول که دوتا رنگ مختلف داره فقط یک سطر در جدول order_product ثبت میشه.
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟