Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

madsynn's avatar

Relationship not returning fields

Hello everyone, Hope you can help me.

Windows 10 / Homestead Laravel 5.1

I have a ecommerce project i am building and here is my problem.

I have the following tables:

  1. products
 Schema::create('products', function (Blueprint $table)
        {
            $table->increments('id');
            $table->string('status')->nullable();
            $table->string('availability')->default('Available');
            $table->string('slug')->nullable();
            $table->string('name')->nullable();
            $table->string('subtitle')->nullable();
            $table->string('manufacturer')->default('The Grace Company');
            $table->longText('details');
            $table->longText('description');

            $table->string('thumbnail')->nullable();
            $table->string('photo_album')->nullable();
            $table->dateTime('pubished_at')->index();
            $table->string('lang', 255);
            $table->timestamps();
            $table->softDeletes();
        });
  1. prices
    Schema::create('prices', function (Blueprint $table)
        {
            $table->increments('id');
            $table->integer('product_id')->unsigned()->index();
            $table->decimal('price', 11, 2)->default('0.00');
            $table->string('model', 12)->nullable();
            $table->string('sku', 12)->default('000000');
            $table->string('upc', 13)->default('000000');
            $table->bigInteger('quantity')->default('99');
            $table->string('alt_details');
            $table->timestamps();
            $table->softDeletes();
            $table->engine = 'InnoDB';
            $table->foreign('product_id')->references('id')->on('products')->onUpdate('cascade')->onDelete('cascade');

        });

I have the following relationships product.php

    public function productPrice() {      return $this->hasMany(Price::class);    }

price.php

 public function product()    {        return $this->BelongsToMany(Product::class);    }

My problem is i cannot get my pricing to store to the alternate table pricing here is my controller store function.

public function store(Request $request) {
$this->validate($request, [
'name' => 'required',
]);
$dest = 'testing/';
$name  = str_random(4) . '_' . $request->file('thumbnail')->getClientOriginalName();
$request->file('thumbnail')->move($dest, $name);
$product = $request->all();
$product['thumbnail'] = '/' . $dest . $name;
$product = Product::create($product);

if ($request->has('productPrices')) {
foreach ($request->productPrices as $price){
if (!empty($price['price'])){
$price = Price::create($request->all());
}
}
}

foreach ($request->categories as $category_id)
        {
            CategoryProduct::create(['category_id' => $category_id, 'product_id' => $product->id]);
        }

FlashAlert()->success('Success!', 'The Product Was Successfully Added');

        return \Redirect(getLang() . '/admin/products');
}

I can store the product just fine but i cannot get it to store the product pricing table data.

any help would be greatly appreciated.

0 likes
34 replies
primordial's avatar

Should a price belong to many products?

try changing price.php

 public function product()    {        return $this->BelongsTo(Product::class);    }

change controller/store

...
$product = Product::create($product);

if ($request->has('productPrices')) {
foreach ($request->productPrices as $price){
if (!empty($price['price'])){
$product->prices()->create($price);
}
...

Good luck.

madsynn's avatar

Thank you for the help @primordial

Ok I was able to get it to start saving but the same data is getting saved in all the fields.

        if(!empty($request->price)){
            foreach($request->price as $productPrice){

                $price = new Price();
                $price->product_id = $product->id;
                $price->price =  $productPrice;
                $price->upc =  $productPrice;
                $price->model =  $productPrice;
                $price->quantity =  $productPrice;
                $price->sku =  $productPrice;
                $price->alt_details =  $productPrice;
                $product->prices()->save($price);
                //dd($price);
            }
        }
madsynn's avatar

@Snapey @primordial Ok here is my complete store method, I am having trouble with 2 areas any help would be appreciated.

  1. pricing stores the same data in all fields
  2. album is not storing fields only the file
public function store(CreateProductRequest $request)
    {


//      /**
//       * Validate the submitted Data
//       */
        $this->validate($request, [
            'name' => 'required',
//          'manufacturer' => 'required',
//          'price' => 'required',
//          'details' => 'required',
//          'quantity' => 'required',
//          'categories' => 'required',
//          'thumbnail' => 'required|image',
//      ]);


        if($request->hasFile('album')){
            foreach($request->album as $photo){
                if($photo && strpos($photo->getMimeType(), 'image') === false){
                    return \Redirect()->back();
                }
            }
        }


        /**
         * Upload a new thumbnail and thumbnail2
         */
        $dest  = 'uploads/products/today/';
        $name  = str_random(11) . '_' . $request->file('thumbnail')->getClientOriginalName();
        $request->file('thumbnail')->move($dest, $name);

        $name2 = str_random(11) . '_' . $request->file('thumbnail2')->getClientOriginalName();
        $request->file('thumbnail2')->move($dest, $name2);
        //$product = $request->all();
        $input = $request->all();

         //dd($input);

        $input['thumbnail'] = '/' . $dest . $name;

        $input['thumbnail2'] = '/' . $dest . $name2;




        $product = Product::create($input, $request->except(
            'attribute_name',
            'product_attribute_value',
            'price',
            'sku',
            'quantity',
            'model',
            'upc',
            'alt_details',
            'feature_name',
            'use_icon',
            'icon',
            'photo_src',
            'alt',
            'caption',
            'photoinfo',
            'linkto',
            'use_main',
            'use_thumb',
            'use_gallery'
        ));





        if(!empty($request->price)){
            foreach($request->price as $productPrice){

                $price = new Price();
                $price->product_id = $product->id;
                $price->price =  $productPrice;
                $price->upc =  $productPrice;
                $price->model =  $productPrice;
                $price->quantity =  $productPrice;
                $price->sku =  $productPrice;
                $price->alt_details =  $productPrice;
                $product->prices()->save($price);
                //dd($price);
            }
        }

//      if($request->has('productPrices')){
//          foreach($request->productPrices as $price){
//              if(!empty($price['price'])){
//                  $product->prices()->create($price);
//              }
//          }
//      }


        /**
         * Upload Album Photos
         */
        if($request->hasFile('album')){
            foreach($request->album as $photo){
                if($photo){
                    $name = str_random(11) . "_" . $photo->getClientOriginalName();
                    $photo->move($dest, $name);

                    AlbumPhoto::create([
                        'product_id' => $product->id,
                        'photo_src' => "/" . $dest . $name,
                        'alt' => $photo->alt,
                        'caption' => $photo->caption,
                        'photoinfo' => $photo->photoinfo,
                        'linkto' => $photo->linkto,
                        'use_main' => $photo->use_main,
                        'use_thumb' => $photo->use_thumb,
                        'use_gallery' => $photo->use_gallery
                    ]);
                }
            }
        }


        /**
         * Linking the categories to the product
         */

        foreach($request->categories as $category_id){
            CategoryProduct::create(['category_id' => $category_id, 'product_id' => $product->id]);
        }

        /**
         * Linking the options to the product
         */

        if($request->has('options')){
            foreach($request->options as $option_details){
                if(!empty($option_details['name']) && !empty($option_details['values'][0])){
                    $option = Option::create([
                        'name' => $option_details['name'],
                        'product_id' => $product->id
                    ]);
                    foreach($option_details['values'] as $value){
                        OptionValue::create([
                            'value' => $value,
                            'option_id' => $option->id
                        ]);
                    }
                }
            }
        }

        if(!empty($request->attribute_name)){
            foreach($request->attribute_name as $key => $item){
                $productVariant = new ProductVariant();
                $productVariant->attribute_name = $item;
                $productVariant->product_attribute_value = $request->product_attribute_value[$key];
                $product->productVariants()->save($productVariant);
            }
        }

        if(!empty($request->feature_name)){
            foreach($request->feature_name as $feature){
                $productFeature = new ProductFeature();
                $productFeature->feature_name = $feature;
                $product->productFeatures()->save($productFeature);

            }
        }

        FlashAlert()->success('Success!', 'The Product Was Successfully Added');
        return \Redirect(getLang() . '/admin/products');
    }

I added except the product create command for all the fields that belong to other tables but not really sure what the function of this is for but thought it was worth a try.

Snapey's avatar

What does the data from the form look like? dd($request->price)

Snapey's avatar

same data in all fields?

if(!empty($request->price)){
            foreach($request->price as $productPrice){

                $price = new Price();
                $price->product_id = $product->id;
                $price->price =  $productPrice;
                $price->upc =  $productPrice;
                $price->model =  $productPrice;
                $price->quantity =  $productPrice;
                $price->sku =  $productPrice;
                $price->alt_details =  $productPrice;
                $product->prices()->save($price);
                //dd($price);
            }
        }

because you put $productPrice in them all???

Snapey's avatar

I added except the product create command for all the fields that belong to other tables but not really sure what the function of this is for but thought it was worth a try.

You need to do this if you have duplicate field names in product and price, otherwise the model just takes the fields that are $fillable and ignores everything else

1 like
madsynn's avatar

@Snapey y ok that has a typo i didnt see it should have been

if(!empty($request->price)){
            foreach($request->prices as $productPrice){

                $price = new Price();
                $price->product_id = $product->id;
                $price->price =  $productPrice;
                $price->upc =  $productPrice;
                $price->model =  $productPrice;
                $price->quantity =  $productPrice;
                $price->sku =  $productPrice;
                $price->alt_details =  $productPrice;
                $product->prices()->save($price);
                //dd($price);
            }
        }

But im not sure if that is correct. The foreach($request->prices as $productPrice){ in the part (->prices) is refering to my relationship in my product model. Am i doing this right?

Snapey's avatar

What does prices look like?

you are clearly assigning the same variable to all the fields. Not sure why?

madsynn's avatar

@Snapey

You need to do this if you have duplicate field names in product and price, otherwise the model just takes the fields that are $fillable and ignores everything else

by fillable do you mean the fillable on all the models that are processing through the controller or just the main primary model. Does it look at them all the same or as all complete.

Example

├── models
     ├── Product  - $fillable = ['id', 'slug', 'ispromo', 'is_published', 'name', 'subtitle', 'details', 'description', 'status', 'thumbnail', 'photo_album', 'pubished_at',  'manufacturer', 'category_id'];
     ├── Price  - $fillable = ['product_id', 'price', 'model', 'sku', 'upc', 'quantity', 'alt_details', 'deleted_at'];
     ├── ProductFeature  - $fillable = ['feature_name', 'useicon', 'icon', 'created_at', 'updated_at'];
     ├── ProductFeature  - $fillable = ['attribute_name', 'attribute_value'];
     └── **ProductController = Combined $fillable from all above models?**

madsynn's avatar

@Snapey

dd($request->price)

array:1 [▼
  0 => "2865575"
]

dd($request->prices)

null

dd($request->all())

array:39 [▼
  "status" => "Available"
  "manufacturer" => "The Company"
  "office_status" => "Draft"
  "is_published" => "1"
  "ispromo" => "0"
  "name" => "name"
  "subtitle" => "subtitle"
  "categories" => array:1 [▶]
  "features_heading" => "features_heading"
  "details" => "details"
  "feature_name" => array:1 [▶]
  "useicon" => "1"
  "icon" => "icon-caret-right"
  "description" => "description"
  "video_url" => "video_url"
  "slug" => "slug"
  "caption" => array:1 [▶]
  "alt" => array:1 [▶]
  "photoinfo" => array:1 [▶]
  "use_main" => array:1 [▶]
  "use_thumb" => array:1 [▶]
  "use_gallery" => array:1 [▶]
  "model" => array:1 [▶]
  "price" => array:1 [▶]
  "quantity" => array:1 [▶]
  "sku" => array:1 [▶]
  "upc" => array:1 [▶]
  "alt_details" => array:1 [▶]
  "meta_title" => "meta_title"
  "meta_keywords" => "meta_keywords"
  "meta_description" => "meta_description"
  "facebook_title" => "facebook_title"
  "google_plus_title" => "google_plus_title"
  "twitter_title" => "twitter_title"
  "attribute_name" => array:1 [▶]
  "product_attribute_value" => array:1 [▶]
  "tracking" => "tracking"
  "datalayer" => "datalayer"
  "_token" => "8RyZcfEXXkAd2iq3Hl0sU193jQ3HtlEeLXQXUiiB"
]

Ok I am not getting how to get the price array returned or stored.

Looking at the above output of request->all it looks like all the data in the request is coming by itself and not in a array. how do i get all the price fields to be in an array when its submitted?

Snapey's avatar

I'm not sure what you mean?

price is an array with a single value. Is that value not what you expected?

Why are you expecting more than one price?

madsynn's avatar

@Snapey

Ok to clarify each product has a main price but can have prices added for different versions of the product. The different versions have different data. So each product can have many different prices depending on the version or variation.

Here is the pricing table to show what i mean.

<table class="table table-striped table-hover table-bordered" id="product-pricing-table">
                        <thead>
                            <tr>
                                <th>Title:</th>
                                <th>Model:</th>
                                <th>Price:</th>
                                <th>Quantity:</th>
                                <th>SKU:</th>
                                <th>UPC:</th>
                            </tr>
                        </thead>
                        <tbody>
                            @if(isset($product) && $product->prices->count()<0)
                                @foreach($product->prices as $price)
                                    <tr class="alt">
                                        <td><input type="text" class="form-control" name="price[price_title]" value="{!! $price->model !!}" /></td>
                                        <td><input type="text" class="text-center form-control" name="price[model]" value="{!! $price->model !!}" /></td>
                                        <td><input type="text" class="text-center form-control currency" name="price[price]" value="{!! $price->price !!}" data-affixes-stay="false" data-prefix="$ " data-thousands="," data-decimal="." /> </td>
                                        <td><input type="text" class="text-center form-control" name="price[quantity]" maxlength="4" value="{!! $price->quantity !!}" /></td>
                                        <td><input type="text" class="text-center form-control" name="price[sku]" value="{!! $price->sku !!}" /></td>
                                        <td><input type="text" class="text-center form-control" name="price[upc]" maxlength="12" value="{!! $price->upc !!}" /></td>
                                    </tr>
                                    <tr class="alt">
                                        <td colspan="1" class="labelTextarea"><label>  <strong>Product Variation Details:</strong></label></td>
                                        <td colspan="5"> <textarea rows="3" class="form-control details-input" name="price[alt_details]" value="{!! $price->alt_details !!}"></textarea></td>
                                    </tr>
                                    <tr class="spacer invis"><td colspan="5"></td></tr>
                                @endforeach
                            @else
                                    <tr class="alt">
                                        <td><input type="text" class="form-control" name="price[price_title]" value="" /></td>
                                        <td><input type="text" class="text-center form-control" name="price[model]" value="" /></td>
                                        <td><input type="text" class="text-center form-control currency" name="price[price]" placeholder="$0.00" data-affixes-stay="false" data-prefix="$ " data-thousands="," data-decimal="." /></td>
                                        <td><input type="text" class="text-center form-control" name="price[quantity]" maxlength="4" /></td>
                                        <td><input type="text" class="text-center form-control" name="price[sku]" value="" /></td>
                                        <td><input type="text" class="text-center form-control" name="price[upc]" maxlength="12" value="636343" /></td>
                                    </tr>
                                    <tr class="alt">
                                        <td colspan="1" class="labelTextarea"><label><strong>Product Variation Details:</strong></label></td>
                                        <td colspan="5"><textarea rows="3" class="form-control details-input" name="price[alt_details]" placeholder="add the details or difference here:"></textarea></td>
                                    </tr>
                                    <tr class="spacer invis"><td colspan="5"></td></tr>
                            @endif
                        </tbody>
                    </table>

That is why the product relationship is set as hasMany and the price is belongsTo.

Sorry i should have clarified that first.

Snapey's avatar

so the problem starts with the form. You can't have repeating sections using the same form field names as you will only get one set of results.

When editing existing records, I would probably name them after the price model id so that you can update the same record later

Its a while since I have done anything like this, but eg

<tr class="alt">
    <td><input type="text" class="form-control" name="price[{{ $price->id}}][price_title]" value="{!! $price->model !!}" /></td>
    <td><input type="text" class="text-center form-control" name="price[{{ $price->id}}][model]" value="{!! $price->model !!}" /></td>
    <td><input type="text" class="text-center form-control currency" name="price[{{ $price->id}}][price]" value="{!! $price->price !!}" data-affixes-stay="false" data-prefix="$ " data-thousands="," data-decimal="." /> </td>
    <td><input type="text" class="text-center form-control" name="price[{{ $price->id}}][quantity]" maxlength="4" value="{!! $price->quantity !!}" /></td>
    <td><input type="text" class="text-center form-control" name="price[{{ $price->id}}][sku]" value="{!! $price->sku !!}" /></td>
    <td><input type="text" class="text-center form-control" name="price[{{ $price->id}}][upc]" maxlength="12" value="{!! $price->upc !!}" /></td>
</tr>

Either the above, or have separate forms for each productPrice. The user changes one row and presses save (on that row) and this is persisted by a productPrice controller as a single record.

If you do it with the array as per the example, you should have an array of prices, each with an array of attributes.

Snapey's avatar

by fillable do you mean the fillable on all the models that are processing through the controller or just the main primary model. Does it look at them all the same or as all complete.

What I mean is that if you pass the entire request to the model for saving, it is only allowed to pick the values from the request that are in its $fillable array.

Send this to the product model;

array:39 [▼
  "status" => "Available"                           // this one
  "manufacturer" => "The Company"                           // this one
  "office_status" => "Draft"
  "is_published" => "1"                         // this one
  "ispromo" => "0"                          // this one
  "name" => "name"                          // this one
  "subtitle" => "subtitle"                          // this one
  "categories" => array:1 [▶]
  "features_heading" => "features_heading"
  "details" => "details"                            // this one                         // this one
  "feature_name" => array:1 [▶]
  "useicon" => "1"
  "icon" => "icon-caret-right"
  "description" => "description"                            // this one
  "video_url" => "video_url"
  "slug" => "slug"                          // this one
  "caption" => array:1 [▶]
  "alt" => array:1 [▶]
  "photoinfo" => array:1 [▶]
  "use_main" => array:1 [▶]
  "use_thumb" => array:1 [▶]
  "use_gallery" => array:1 [▶]
  "model" => array:1 [▶]
  "price" => array:1 [▶]
  "quantity" => array:1 [▶]
  "sku" => array:1 [▶]
  "upc" => array:1 [▶]
  "alt_details" => array:1 [▶]
  "meta_title" => "meta_title"
  "meta_keywords" => "meta_keywords"
  "meta_description" => "meta_description"
  "facebook_title" => "facebook_title"
  "google_plus_title" => "google_plus_title"
  "twitter_title" => "twitter_title"
  "attribute_name" => array:1 [▶]
  "product_attribute_value" => array:1 [▶]
  "tracking" => "tracking"
  "datalayer" => "datalayer"
  "_token" => "8RyZcfEXXkAd2iq3Hl0sU193jQ3HtlEeLXQXUiiB"
]

(I may have missed a couple) The point being, that all the other fields are ignored.

By the way, there should never be a case of having id in the $fillable array

1 like
madsynn's avatar

@Snapey Thank you for helping me understand that.

So if the only values i can put in the create method how do i add the values that are in arrays?

array:39 [▼
  "status" => "Available"                           // this one
  "manufacturer" => "The Company"                           // this one
  "office_status" => "Draft"
  "is_published" => "1"                         // this one
  "ispromo" => "0"                          // this one
  "name" => "name"                          // this one
  "subtitle" => "subtitle"                          // this one
  "categories" => array:1 [▶]                //inArray How do I add it to the db:table 
  "features_heading" => "features_heading"
  "details" => "details"                            // this one                         // this one
  "feature_name" => array:1 [▶]                //inArray How do I add it to the db:table 
  "useicon" => "1"
  "icon" => "icon-caret-right"
  "description" => "description"                            // this one
  "video_url" => "video_url"
  "slug" => "slug"                          // this one
  "caption" => array:1 [▶]                //inArray How do I add it to the db:table 
  "alt" => array:1 [▶]                //inArray How do I add it to the db:table 
  "photoinfo" => array:1 [▶]                //inArray How do I add it to the db:table 
  "use_main" => array:1 [▶]                //inArray How do I add it to the db:table 
  "use_thumb" => array:1 [▶]                //inArray How do I add it to the db:table 
  "use_gallery" => array:1 [▶]                //inArray How do I add it to the db:table 
  "model" => array:1 [▶]                //inArray How do I add it to the db:table 
  "price" => array:1 [▶]                //inArray How do I add it to the db:table 
  "quantity" => array:1 [▶]                //inArray How do I add it to the db:table 
  "sku" => array:1 [▶]                //inArray How do I add it to the db:table 
  "upc" => array:1 [▶]                //inArray How do I add it to the db:table 
  "alt_details" => array:1 [▶]
  "meta_title" => "meta_title"
  "meta_keywords" => "meta_keywords"
  "meta_description" => "meta_description"
  "facebook_title" => "facebook_title"
  "google_plus_title" => "google_plus_title"
  "twitter_title" => "twitter_title"
  "attribute_name" => array:1 [▶]                 //inArray How do I add it to the db:table 
  "product_attribute_value" => array:1 [▶]                //inArray How do I add it to the db:table 
  "tracking" => "tracking"
  "datalayer" => "datalayer"
  "_token" => "8RyZcfEXXkAd2iq3Hl0sU193jQ3HtlEeLXQXUiiB"
]
madsynn's avatar

@ctomasz @Snapey

Thanks for the info but I am looking for an example of how to submit the requested form data into sub tables in my product store method.

something along the lines of this:

 if(!empty($productPricing)){
             foreach ($productPricing as $productPrice)
             {
                 Price::create([
                     'title' => $productPrice->title,
                     'price' => $productPrice->price,
                     'model' => $productPrice->model,
                     'sku' => $productPrice->sku,
                     'upc' => $productPrice->upc,
                     'quantity' => $productPrice->quantity,
                     'alt_details' => $productPrice->alt_details
                 ]);
             }
         }

The data is submitted form the create product form and needs to be submitted into a seperate database with id corresponding to the product itself.

Snapey's avatar

Unfortunately you have not shared the form, which is where the problem starts

First, If you are not keeping track of the price->id then when saving the product, you must first delete all existing prices since you will create all new records from form data.

Secondly, each price, with all its attributes, must come from the form with a unique key so that they can be separated out into individual writes. I suggested this as by adding the price->id to each row in the prices table, but it does not need to be the id, it can be a simple counter

<td><input type="text" name="price[$i]['sku']"></td>
<td><input type="text" name="price[$i]['upc']"></td>
<?php $i++>
</tr>

The point is that price has two levels of array indices price[level 1][level 2] level 1 groups all the attributes for one price, level2 is all the individual price attributes. Your earlier code just used the name price over and over so you were not creating the right form data structure.

You will then get back from the form, a simple multi-dimension array, each top level representing one row in your table. You can then iterate over these with your for each.

just another observation;

I generally name relationships that are hasMany as plurals so productPrice() on product, I would have called prices so that I can remember the relationship, and product where it is a belongsTo on the Price model

1 like
madsynn's avatar

@Snapey Thank you for the great info. I am going to try it now. Sorry i forgot the form. Here is the form for my pricing.

JS

$("#addRow").click(function (e) {
        var i = 0;  
    i++;
            console.log("Insert Data For New Product Price");
             e.preventDefault();
              $("#addRow").click(function() {
                   var row = $("<tr>" + "<td><input type='text' class='text-center form-control' name='price[i]['title']' /></td><td><input type='text' class='text-center form-control' name='price[i]['model']' /></td>" +
                   "<td><input type='text' class='text-center form-control  currency' name='price[i]['price']' placeholder='$0.00' data-affixes-stay='false' data-prefix='$ ' data-thousands=',' data-decimal='.' /></td>" +
                   "<td><input type='text' class='text-center form-control' name='price[i]['quantity']' /></td>" +
                   "<td><input type='text' class='text-center form-control' name='price[i]['sku']' /></td>" +
                   "<td><input type='text' class='text-center form-control' name='price[i]['upc']' value='636343' /></td>" +
                   "</tr>" + "<tr class='alt'><td colspan='1' class='text-center labelTextarea'><label ><strong>Product Variation Details:</strong></label></td>" +
                   "<td colspan='4'><textarea rows='3' class='form-control details-input' name='price[i]['alt_details']' placeholder='add the details or difference here:'></textarea></td>" +
                   "</tr>");
                   $("table#product-pricing-table tbody").append(row);
                   $('table#product-pricing-table input.currency').maskMoney();
               });
               $(function() {
                   $('table#product-pricing-table input.currency').maskMoney();
               });

HTML

 <table class="table table-striped table-hover table-bordered" id="product-pricing-table">
                        <thead>
                            <tr>
                                <th>Title:</th>
                                <th>Model:</th>
                                <th>Price:</th>
                                <th>Quantity:</th>
                                <th>SKU:</th>
                                <th>UPC:</th>
                            </tr>
                        </thead>
                        <tbody>
                            @if(isset($product) && $product->prices->count()<0)
                                @foreach($product->prices as $price)
                                    <tr class="alt">
                                        <td><input type="text" class="form-control" name="price[i]['title']" value="{!! $price->model !!}" /></td>
                                        <td><input type="text" class="text-center form-control" name="price[i]['model']" value="{!! $price->model !!}" /></td>
                                        <td><input type="text" class="text-center form-control currency" name="price[i]['price']" value="{!! $price->price !!}" data-affixes-stay="false" data-prefix="$ " data-thousands="," data-decimal="." /> </td>
                                        <td><input type="text" class="text-center form-control" name="price[i]['quantity']" maxlength="4" value="{!! $price->quantity !!}" /></td>
                                        <td><input type="text" class="text-center form-control" name="prices[sku]" value="{!! $price->sku !!}" /></td>
                                        <td><input type="text" class="text-center form-control" name="price[i]['upc']" maxlength="12" value="{!! $price->upc !!}" /></td>
                                   
                                    </tr>
                                    <tr class="alt">
                                        <td colspan="1" class="labelTextarea"><label>  <strong>Product Variation Details:</strong></label></td>
                                        <td colspan="5"> <textarea rows="3" class="form-control details-input" name="price[i]['alt_details']" value="{!! $price->alt_details !!}"></textarea></td>
                                    </tr>
                                    <tr class="spacer invis"><td colspan="5"></td></tr>
                                @endforeach
                            @else
                                    <tr class="alt">
                                        <td><input type="text" class="form-control" name="price[i]['title']" value="" /></td>
                                        <td><input type="text" class="text-center form-control" name="price[i]['model']" value="" /></td>
                                        <td><input type="text" class="text-center form-control currency" name="price[i]['price']" placeholder="$0.00" data-affixes-stay="false" data-prefix="$ " data-thousands="," data-decimal="." /></td>
                                        <td><input type="text" class="text-center form-control" name="price[i]['quantity']" maxlength="4" /></td>
                                        <td><input type="text" class="text-center form-control" name="price[i]['sku']" value="" /></td>
                                        <td><input type="text" class="text-center form-control" name="price[i]['upc']" maxlength="12" value="636343" /></td>
                               
                                    </tr>

                                    <tr class="alt">
                                        <td colspan="1" class="labelTextarea"><label><strong>Product Variation Details:</strong></label></td>
                                        <td colspan="5"><textarea rows="3" class="form-control details-input" name="price[$i]['alt_details']" placeholder="add the details or difference here:"></textarea></td>
                                    </tr>
                                    <tr class="spacer invis"><td colspan="5"></td></tr>
                            @endif
                        </tbody>
                    </table>
madsynn's avatar

@Snapey

I tried what you recommended but to no avail. can you please take a look at my files and see if you can find why i cannot get the prices to save to the database. I have worked on this for a week now and am really frustrated. Do you by chance freelance?

my files are added to this.

https://github.com/madsynn/laravelEcom.git

Thank you for taking the time to help me.

Snapey's avatar

I have a copy of your app. Where is the issue (which controller / view)?

Snapey's avatar

OK, this is what I meant earlier;

here you are looping over prices but giving them all the same identity, so there is no way to differentiate between the price fields when they are returned. Give each row a unique price key, and since every existing price has an id then why not use that?

    @foreach($product->prices as $price)
        <tr class="alt">
            <td><input type="text" class="form-control" name="prices[{{ $price->id }}][title]" value="{!! $price->model !!}" /></td>
            <td><input type="text" class="text-center form-control" name="prices[{{ $price->id }}][model]" value="{!! $price->model !!}" /></td>
            <td><input type="text" class="text-center form-control currency" name="prices[{{ $price->id }}][price]" value="{!! $price->price !!}" data-affixes-stay="false" data-prefix="$ " data-thousands="," data-decimal="." /> </td>
            <td><input type="text" class="text-center form-control" name="prices[{{ $price->id }}][quantity]" maxlength="4" value="{!! $price->quantity !!}" /></td>
            <td><input type="text" class="text-center form-control" name="prices[{{ $price->id }}][sku]" value="{!! $price->sku !!}" /></td>
            <td><input type="text" class="text-center form-control" name="prices[{{ $price->id }}][upc]" maxlength="12" value="{!! $price->upc !!}" /></td>
        </tr>
        <tr class="alt">
            <td colspan="1" class="labelTextarea"><label>  <strong>Product Variation Details:</strong></label></td>
            <td colspan="5"> <textarea rows="3" class="form-control details-input" name="prices[{{ $price->id }}][alt_details]" value="{!! $price->alt_details !!}"></textarea></td>
        </tr>
        <tr class="spacer invis"><td colspan="5"></td></tr>
    @endforeach
Snapey's avatar
Snapey
Best Answer
Level 122

Saving;

        //needs more thought about handling new prices. This just copes with editing existing ones
        foreach ($request->prices as $productPrice)
        {
            $price =  Price::findOrFail($productPrice['id'])

            $price->title       = $productPrice['title'];
            $price->price       = $productPrice['price'];
            $price->model       = $productPrice['model'];
            $price->sku         = $productPrice['sku'];
            $price->upc         = $productPrice['upc'];
            $price->quantity    = $productPrice['quantity'];
            $price->alt_details = $productPrice['alt_details'];
            $price->save();
        }

        //or, assuming $fillable correct on model..
        foreach ($request->prices as $productPrice) {
            Price::where('id',$productPrice['id'])->update($productPrice);
        }
madsynn's avatar

@Snapey

Thank you for your help i will try them in the morning. I have another question about the saving also. When i does save it saves all new prices but ties them to the product id. which is what its supposed to do. but in my products view in the admin instead of the product listing only once it is listing the product for each new product. Do you know why its doing this. that would be the product.blade.php in the backend/ecom/products/ part of the views.

madsynn's avatar

@Snapey " //needs more thought about handling new prices. This just copes with editing existing ones"

Not sure what you mean here. wouldn't this be handled in the store method. this is the part im having troubles with. the $product = new Product::create(); is the part that will not work for me.

Snapey's avatar

Not quite sure why this is so difficult to grasp?

If you have a bunch of prices on a form, then they all need a unique key so that they can be represented at the backend. In the examples I gave I used the existing Price id as the unique key and then overwrote the previous value in the database. This is an edit function after all.

//needs more thought about handling new prices. This just copes with editing existing ones"

what I mean here is that you have an edit form, where maybe you have 4 price variations listed, with SKU code, etc for each

then in your form, you have the option to add extra rows for more variants. Each of these new rows must be uniquely identified .

Your options.

  1. Use the example I have shown, but then create the new rows with a name like name="newPrice[i]['sku'] where i starts at 0 and increments by 1 each time you add a new row. Then in the save method, loop through the prices as I showed, and then do the same again, but this time foreach($request->newPrice as $np) or similar and Create new entries rather than updating existing ones as in my example.

  2. Don't use the existing price id, and just assign a counter to each row in the table, irrespective if its a new price or not. In the save method, first delete all the old product prices (bear in mind if there is a fault in saving you could lose all the rows), and then create all new prices.

instead of the product listing only once it is listing the product for each new product.

This does not make a lot of sense? Not sure what you mean?

madsynn's avatar

@Snapey Thank you for your response.

instead of the product listing only once it is listing the product for each new product.

What i mean here is in my admin when i got to products.blade.php where i get a list of all the products, when i create a new product with multiple prices it saves as the same product the same number of the alternate prices. Instead of one product.

question on:

Don't use the existing price id, and just assign a counter to each row in the table, irrespective if its a new price or not. In the save method, first delete all the old product prices (bear in mind if there is a fault in saving you could lose all the rows), and then create all new prices.

So you are telling me not to use a counter here because it might overwrite the products that are already listed in those rows. correct? how would i add new prices. The product->price has not been created yet so i cannot get the priceID what can i use for this part. i see you use prices[{{ $price->id }}][quantity] with $price->id but until i save the product the price does not have an id correct?

Snapey's avatar

I thought this was an edit function, and you are passing a collection of prices?

In your code;

@foreach($product->prices as $price)

so you are looping through all the existing prices for the product? Each of these will have an id according to the entry in the prices table.

I think you need to be clear here. are you creating a new product from scratch or are you editing one that exists already?

madsynn's avatar

@Snapey Sorry about that i thought i clarified it already. I am creating new product with multiple prices. The update stuff you helped me with will probably work great if i can get them created.

Next

Please or to participate in this conversation.