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

نحوه ذخیره کردن آرایه در جدول رابط توسط متد sync

سلام دوستان. من هنگام ایجاد محصول جدید یه بخش اضافه کردم که رنگ محصول به همراه قیمت و موجودی محصول رو انتخاب میکنم.
در ضمن جدول colors با جدول products رابطه چند به چند داره.
و بوسیله جاوا اسکریپ id ها رو گروه بندی کردم تا مشخص بشه که قیمت و موجودی مربوط به کدام رنگ هست. به این شکل :

name="colors[${id}][color]" => آدی رنگ 
name="colors[${id}][pricecolor]" => آی دی قیمت
name="colors[${id}][inventory]" => آی دی موجودی

بعد اومدم و در productController اون رنگ رو اعتبار سنجی کردم. به این شکل:

 $color_validate = $request->validate([
            'colors.*.color' => 'required',
            'colors.*.pricecolor'   => 'required|min:3',
            'colors.*.inventory'   => 'required'
        ]);

الان میخام این ویژگی هارو در جدول واسط colorproduct ثبت کنم.
جدول colorproduct :

color_product:
color_id
product_id
pricecolor
inventory

خوب دوستان الان سوال من این هست که چجوری این ویژگی ها(رنگ و قیمت و موجودی ) رو در جدول واسط ذخیره کنم؟
مدل product :

 public function colors() 
    {
        return $this->belongsToMany(Color::class)->withPivot(['pricecolor', 'inventory']);;
    }

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

با عرض پوزش کد زیر تست کن
چون ارایه هست من به صورت object اشتباهن درخواست دادم

$product->colors()->sync($color_validate['colors']);

رضا پارسیان
تخصص : توسعه دهنده Php , Laravel
@Rp76 3 سال پیش مطرح شد
0

سلام وقتتون بخیر!‍

کد به این شکل هست اگر اشتباه نکنم.

$product->colors()->sync([
"color_id"=>"1"
],false);

اون false رو اگر نذاری دیتا های قبلی رو پاک میکنه.

اول باید محصول رو select کرده باشی.
و دیگه به product_id نیاز نداری یعنی نمی‌خواد پاس بدی برای ثبت


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

@Rp76
سلام در روشی که شما گفتین نمیشه از $color_validate رنگ (color) رو به "color_id" پاس داد. برای همین من از کالکشن و از متد each استفاده کردم. به این صورت:

collect($color_validate['colors'])->each(function($color) use($product) {

       // dd($image['color']);
        $product->colors()->sync([
                'color_id' => $color['color'],
                'pricecolor' => $color['pricecolor'],
                'inventory' => $color['inventory'],
        ]);
    });

اما این ارور رو میده:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (shop_mobi_db.color_product, CONSTRAINT color_product_color_id_foreign FOREIGN KEY (color_id) REFERENCES colors (id) ON DELETE CASCADE) (SQL: insert into color_product (color_id, product_id) values (5000, 63))


رضا پارسیان
تخصص : توسعه دهنده Php , Laravel
@Rp76 3 سال پیش مطرح شد
0

یعنی چی روشی که من گفتم نمیشه؟

اصولش همونه چرا نمیشه
اصلا من متوجه نشدم!!


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

سلام
یه زحمتی بکش با dd خروجی $color_validate رو نمایش بده به صورت ارایه داده هاشو

فقط کافیه داده هات با همون نام توی یک آرایه باشه نیاز به اون حلقه نداری
بهتره داده هات رو به صورت json ذخیره کنی توی جاوا اسکریپت
مثلا

    var color=[];
    color.push({
        color_id:'',
        color:'',
        pricecolor:'',
        inventory:'',
});

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

    public function products()
    {
        return $this->belongsToMany(Product::class)->withPivot(['pricecolor', 'inventory']);;
    }

دوست عزیزمون کدی که نوشته به نظرم اشتباهه چون داره برای یک product رنگ ذخیره میکنه درصورتی که من فقط color_id میبینم وproduct ندیدم
اگر product اول ذخیره میشه و بر میگرده اطلاعاتش اره اوکیه اون ولی اشاره بهش نشد که در این صورت نبود product_id هم اشتباهه
با فرض ذخیره ی product باز هم اون کد باید اشتباه باشه چون فقط یک ایدی بهش داده شده
در صورتی که برای اون محصول باید سه پارامتر دیگه مشخص بشه color_id و pricecolor و inventory
بعد کافیه اون داده ها رو به صورت ارایه بهش بدی
یه همچین جمع اوری ای برای داده هات داشته باش توی کنترلر
حالا اونجا که sync میکنیم و میخواییم داده ای پاک نشه false میزاریم خب مستقیما از attach استفاده کنیم
خیلی فرق نی حالا


        $colors=[];
        foreach ($color_validate as $color){
            $colors[]=[
                'color_id'=>$color['id'],
                'pricecolor'=>$color['id'],
                'inventory'=>$color['id']
            ];
        }
        $product->colors()->attach($colors);
//        $order->products()->sync($colors);

شما اون چیزی که با جاوا اسکریپت جمع کردیشم خروجی بده ببینیم چی در میاد
و کنترلرت برای ذخیره کردن بحث product رو هم بهمون نشون بدی بد نی


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

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


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

product چی؟ ذخیره میکنی ؟
به جای color توی همین خروجی که نشون دادی بنویس colorid تا کارت راحت تر بشه و با کد زیر کارت راه بیفته
شما داری توی جدول واسط 4 تا فیلد پر میکنی دیگ

$product->colors()->attach($colors);

ببین من یه کد مثل تو دارم توی برنامم بهت نشون میدم ببینی ب صورت نمونه

        $order=auth()->user()->orders()->create($request->all());

        $validated=$request->products->validate([
            'product_id'=>'required',
            'count'=>'required',
            'price'=>'required',
        ]);
        $order->products()->sync($validated);

order من نقش product تورو داره و prodcut من نقش color تو

اول سفارشمو ثبت کردم بعد برای اون سفارش محصولاتش رو با قیمت و تعداد که شما هم دو تا فیلد مثل من اضاف داری

شما هم اول محصول بعد رنگ و قیمتو اینا


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

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

 public function store(Request $request)
    {
       // return $request->all();
        $data = $request->validate([
            'title' => ['required', 'string', 'max:200'],
            'description' =>'required',
            'price' => 'required',
            'categories' => 'required',
            'attributes' => 'array',
            'image' => 'required|image|max:200|min:5'

        ]);

        $color_validate = $request->validate([
            'color' => 'required',
            'pricecolor'   => 'required',
            'inventory'   => 'required'
        ]);

    $file = $data['image'];
    $destinationPath = '/images/products/' . now()->year . '/' . now()->month . '/' ;
    $file->move(public_path($destinationPath) ,  $file->getClientOriginalName());

    $data['image'] = $destinationPath . $file->getClientOriginalName();

      $product =  auth()->user()->products()->create($data);

      $product->colors()->attach($color_validate);   👈👈👈

      $product->categories()->sync($data['categories']);

     $attributes = collect($data['attributes']);

     $attributes->each(function($item) use($product){
         if(is_null($item['name']) || is_null($item['value'])) return;

         $attr = Attribute::firstOrCreate(
             ['name' => $item['name']]
         );

         $attr_value = $attr->values()->firstOrCreate(
             ['value' => $item['value']]
         );

         $product->attributes()->attach($attr->id, ['value_id' => $attr_value->id]);

     });
        alert()->success('محصول مورد نظر با موفقیت ایجاد شد');
        return redirect(route('admin.products.index'));
    }

اینجا من دقیقا عین شما عمل کردم ولی به این خطا خوردم:
SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'field list' (SQL: insert into color_product (color_id, product_id, 0, 1) values (color, 89, 2, 3), (pricecolor, 89, 30000, 20000), (inventory, 89, 30, 20))
اینم جدول واسط:

و اینم کد های ویو:

 <select class="form-control image_label" name="color[]" id="color_warranty" aria-label="Image" aria-describedby="button-image" >

                                    @foreach (\App\Color::all() as $color )
                                        <option value="{{ $color->id }}" >
                                        {{$color->name}}
                                         - 
                                         @foreach ($color->warranties as $warr)
                                            <span class="text-primary">
                                             {{$warr->name}}
                                            </span>

                                         @endforeach

                                         - 
                                         قیمت افزوده:
                                         {{$color->pricecolor}}
                                           تومان
                                         </option>
                                    @endforeach

                                  </select>

                                </div>
                            </div>
                        </div>

                        <div class="col-3">
                            <div class="form-group">
                                 <label>قیمت افزوده</label>
                                 <input type="text" name="pricecolor[]" class="form-control">
                            </div>
                        </div>

                        <div class="col-3">
                            <div class="form-group">
                                 <label>موجودی </label>
                                 <input type="text" name="inventory[]" class="form-control">
                            </div>
                        </div>

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

خب ببین قرار شد به جای color از color_id استفاده کنی که توی دیتا بیس ذخیره بشه
فقط اینکه چزا سر ستون صفر و یک گذاشته ک ارور داده رو تعجبم که از چی این نوشته
شما اول color توی ویو رو بکن color_id بعد اون validate که مال رنگه رو هم بکن color_id بعد تست کن اگر نشد دوباره از validate یک dd بگیر بی زحمت


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

@salar.mohammad2013
سلام امتحان کردم نشد متاسفانه این ارور رو میده :
SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'field list' (SQL: insert into color_product (color_id, product_id, 0, 1) values (colorid, 94, 2, 3), (pricecolor, 94, 50000, 90000), (inventory, 94, 20, 9))

اینم خروجی $colorvalidate :

array:3 [▼
  "color_id" => array:2 [▼
    0 => "2"
    1 => "3"
  ]
  "pricecolor" => array:2 [▼
    0 => "50000"
    1 => "90000"
  ]
  "inventory" => array:2 [▼
    0 => "20"
    1 => "9"
  ]
]

من فکر می کنم کلا اشتباه داریم میریم جلو یا یه یه مورد کلیدی رو یادمون رفته.


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

@Rp76
سلام روش شما رو به این شکل تست کردم ولی خطای SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'field list' (SQL: insert into color_product (color_id, product_id, 0, 1) values (color_id, 100, 2, 3)) رومیده.

$test =  $product->colors()->sync([
       "color_id" => $color_validate['color_id'],
        "pricecolor"=>$color_validate['pricecolor'],
        "inventory"=>$color_validate['inventory'],

        ],false);

رضا پارسیان
تخصص : توسعه دهنده Php , Laravel
@Rp76 3 سال پیش مطرح شد
0

سلام دوباره.
من فراموش کردم که بگم
من این کد رو همین جا و همین لحظه زدم و ممکنه مشکل داشته باشه ولی کار همین هست
کد جدید

$test =  $product->colors()->sync([

     [
  "color_id" => $color_validate['color_id'],

        "pricecolor"=>$color_validate['pricecolor'],

        "inventory"=>$color_validate['inventory'],
]

        ],false);

باید ارایه ای از ارایه ها ارسال کنید


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

ببین داده ی قبلی ای که نشون دادی برای color اوکی بود
برای هر اندیس ما یک سری اطلاعات داشتیم
توی این داده که داری نشون میدی برای color_id مثلا دو تا داده داری و بعد برای pricecolor باز دو تا خب کدوم رو بفهمه برای کدومه
خروجی مقادیر باید مثل این باشه console.log کردم
خروجی
شما این داده ای که پایین الان میزارم که برای رنگ با ایدی 2 و 3 هست رو به صورت دستی بزای توی جاوا اسکریپتت و این داده رو ارسال کن ک فرمت اطلاعات از یک طرف درست باشه اول بقیه مشکلات رو بگیریم بعدش

    var colors=[
        {color_id:2,colorprice:10000,inventory:6},
        {color_id:3,colorprice:40000,inventory:2}
    ]

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

@Rp76
سلام امتحان کردم این ارور رو میده Array to string conversion
اینم خروجی $color_validate :

array:3 [▼
  "color_id" => array:2 [▼
    0 => "2"
    1 => "3"
  ]
  "pricecolor" => array:2 [▼
    0 => "20000"
    1 => "3000"
  ]
  "inventory" => array:2 [▼
    0 => "20"
    1 => "3"
  ]
]

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

باز هم ک خروجی قبله اون خطا اگر توی ویو واسه جیسون هست داده رو JSON.stringify(color) با این متد string کن بفرستش
خروجیت باید مثل چیزی که فرستادم بشه نوع چینشت بعد ببریش توی sync


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

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

array:1 [▼
  "colors" => array:2 [▼
    0 => array:3 [▼
      "color_id" => "2"
      "pricecolor" => "5000"
      "inventory" => "5"
    ]
    1 => array:3 [▼
      "color_id" => "3"
      "pricecolor" => "400000"
      "inventory" => "40"
    ]
  ]
]

حالا بفرمایید به چه شکل در جدول واسط ذخیره کنم


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

نه این در جواب آقا رضا فرستادم

سلام امتحان کردم این ارور رو میده Array to string conversion
اینم خروجی $color_validate :


رضا پارسیان
تخصص : توسعه دهنده Php , Laravel
@Rp76 3 سال پیش مطرح شد
0

شماره تماس من توی پروفایلم هست!
بهم پیام بده


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

@Rp76
@salar.mohammad2013
ممنون دوستان بابت تایمی که در اختیار من قرار دادین.
بلاخره حلش کردم . به این شکل: قدم اول : گروه بندی id ها در سمت ویو توسط جاوا اسکریپت برای اینکه معلوم بشه اون قیمت و موجودی مربوط به کدوم رنگ میشه :

name="colors[${id}][color_id]"
colors[${id}][pricecolor]
colors[${id}][inventory]

قدم دوم: اعتبار سنجی اطلاعات:

  $color_validate = $request->validate([
            'colors.*.color_id' => 'required',
            'colors.*.pricecolor'   => 'required',
            'colors.*.inventory'   => 'required'
        ]);

قدم سوم : پیمایش آیتم های لست در حلقه و در نهایت ذخیره در جدول واسط :

 foreach($color_validate as $colors)
        {
            $test =   $colors;
        }

$product->colors()->sync($test);

و تمام!
اینم خروجی:


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

خب خدارو شکر اوکیه
مشکل اصلیت اشکال در ارسال اطلاعاتت بود
فقط چون حلقه foreach که داری توی ارایه نمیریزه داده رو و داری هر بار متغییر test رو مقدار دهی مجدد میکنی عملا اشتباه میشه
ولی حس میکنم چون حلقه رو روی validate زدی کلا یه ایندکس بیشتر نداره و خروجی ب نظرم باید test و colorvalidate یک مقدار باشن یه جورایی

یه dd برای validate و یه dd برای test قبل sync بزار دو تا اسکرین شات میشه زحمتت بفرست ببینم چیه خروجیش
حالا کدت ک کار میکنه کاری ندارم ولی تعجبمه حلقت


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

@salar.mohammad2013
سلام بفرماید خروجی $color_validate :

array:1 [▼
  "colors" => array:2 [▼
    0 => array:3 [▼
      "color_id" => "2"
      "pricecolor" => "5000"
      "inventory" => "20"
    ]
    1 => array:3 [▼
      "color_id" => "3"
      "pricecolor" => "30000"
      "inventory" => "3"
    ]
  ]
]

اینم خروجی $test :

array:2 [▼
  0 => array:3 [▼
    "color_id" => "2"
    "pricecolor" => "5000"
    "inventory" => "20"
  ]
  1 => array:3 [▼
    "color_id" => "3"
    "pricecolor" => "30000"
    "inventory" => "3"
  ]
]

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

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