Home > OS >  laravel store combined data as object in a single field
laravel store combined data as object in a single field

Time:08-24

I am trying to store repeater data in database Using laravel. But for that I need to combine some data with different values.

my form looks like this--

 <div v-for="(tab, tabIndex) in tabs" :key="tab.id">
            <div >
                <label>HouseAreaTypes</label>
            </div>
            <div >
                <select
                    v-model="tab.selectedHouseType"
                    @change="getDecor(tabIndex)"
                    name="houseAreaTypeId">
                    <option v-for="houseType in houseTypes" :key="houseType.id" :value="houseType.id">{{ houseType.name }}</option>
                </select>
                <div >
                    <button @click="addTab">
                        <i ></i>
                    </button>
                    <button v-if="tabIndex > 0"  @click="removeTab(tabIndex, tab)">
                        <i ></i>
                    </button>
                </div>
            </div>
            <div v-for="(row, rowIndex) in tab.rows" :key="row.id">
                <table >
                    <thead>
                    <th>DecorationType</th>
                    <th>Description</th>
                    <th >Rate</th>
                    <th>Quantity</th>
                    <th >TotalAmount</th>
                    <th ></th>
                    </thead>
                    <tbody>
                    <td>
                        <select
                            v-model="row.selectedDecor"
                            @change="getDescription(tabIndex,rowIndex) "name="decId">
                            <option v-for="decorType in tab.decorTypes" :key="decorType.id" :value="decorType.id">
                                {{ decorType.name }}
                            </option>
                        </select>
                    </td>
                    <td >
                        <input type="text" name="des" v-model="row.selectedDes"/>
                    </td>
                    <td >
                        <input type="number" name="rate" v-model="row.selectedRate" @change="calculateLineTotal(tabIndex,rowIndex)"
                        />
                    </td>
                    <td >
                        <input type="number" min="0" name="qty" v-model="row.selectedQty" @change="calculateLineTotal(tabIndex,rowIndex)"
                        />
                    </td>
                    <td >
                        <input
                            type="number" name="totalAmount" v-model="row.line_total"/>
                    </td>
                    <td>
                        <button  v-if="rowIndex == Object.keys(tab.rows).length -1" type="button"  @click="addRow(tabIndex)">
                            <i ></i>
                        </button>
                        <button  type="button"
                                @click="removeRow(rowIndex, row,tabIndex)">
                            <i ></i>
                        </button>
                    </td>
                    </tbody>
                </table>
                <hr />
            </div>
        </div>

my migration looks like this--

 Schema::create('house_area_carts', function (Blueprint $table) {
            $table->id();
            $table->integer('houseAreaTypeId')->nullable();
            $table->text('houseAreaCartInfo')->nullable()->comment('Object (decorationTypeId, descriptionOfDecoration, qty, rate, totalAmount)');
            $table->timestamps();
        });

I already have done the frontend part using vue. Here I need to store multiple houseAreaTypeId but in the houseAreaCartInfo I need to commbine decorationTypeId, descriptionOfDecoration, qty, rate, totalAmount these datas. I am attaching an image so you understand well

Iamge to understand the topic

updates

in my controller --

public function createCart(Request $request, $id)
    {
        $cart = HouseAreaCart::create([
            'houseAreaTypeId' => $request->houseAreaTypeId,
            'houseAreaCartInfo' => $request->get('houseAreaCartInfo'),
            'houseAreaCartInfo' =>[
                'rate' => $request->rate,
                'qty' => $request->qty,
                'decId' => $request->decId,
                'des' => $request->des,
                'totalAmount' => $request->totalAmount
            ]
        ]);
        dd($cart);
        return response()->json($cart);
    }

I am getting this after dd.

 "houseAreaTypeId" => "2"
    "houseAreaCartInfo" => "{"rate":["11","2"],"qty":["8","1"],"decId":["2","3"],"des":["Nostrum dolorem qui","Veniam architecto l"],"totalAmount":["88.00","2.00"]}"

But when I add another houseAreaTypeId it's showing only the last houseAreaTypeId I added.

Now how do I process multiple houseAreaTypeId in my controller and save it in the database?

CodePudding user response:

The easieast way will be attribute casting to json or array:

// add to the model:
protected $casts = [
  'houseAreaCartInfo' => 'array',
];

https://laravel.com/docs/9.x/eloquent-mutators#array-and-json-casting

In the controller you would simply assign to the model an array from your request (or use update method on the model - will work the same):

$cartModel->houseAreaCartInfo = $request->get('houseAreaCartInfo');

then whenever you get that value it will come as an array (same as in the request):

$cartModel->houseAreaCartInfo

[
  'des' => ...,
  'qty' => ...,
  ...
]

In your request I suggest validation to make sure this value comes as an array and is stored properly https://laravel.com/docs/9.x/validation#validating-arrays

CodePudding user response:

Your migration should like,

$table->text('houseAreaCartInfo')->nullable()

anf then, Make sure your request is something like the following,

$request = [
    'houseAreaTypeId' => 'required|int', //or array as your choice
    'houseAreaCartInfo' => 'required|array',
    'houseAreaCartInfo.*.decerationType' => 'required|array', //or int as your choice
    'houseAreaCartInfo.*.description' => 'required|string',
    'houseAreaCartInfo.*.rate' => 'required|int',
    'houseAreaCartInfo.*.quantity' => 'required|int',
];

Then in your model, cast the column as array,

protected $cast = [
    'houseAreaCartInfo' => 'array'
];

Finally, you can create model by using eloquent, There should be no error.

  • Related