简体   繁体   中英

Update method in laravel are going to create a new model in database

I am facing a problem in laravel restful api building,

I have the following controller

 <?php
 namespace App\Http\Controllers\Kittrans;
 use App\Http\Controllers\Controller;
 use App\Inventory;
 use App\Kittrans;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\DB;

 class KittransController extends Controller
 {

 public function index()
 {

 }
/**
 * Show the form for creating a new resource.
 *
 * @return \Illuminate\Http\Response
 */
public function create()
{
    //
}

/**
 * Store a newly created resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function store(Request $request)
{

     $rules =[
    'kmo_id' => 'required',
    'item_id' => 'required|integer|min:1',
    'store_id' => 'required|integer|min:1',
    'count' => 'required|integer|min:1'
    ];

    $this->validate($request,$rules);

    // check if requested count of item less than or equal to count in store
    $inventory = DB::table('inventories')->where(
        [
        ['item_id','=',$request->input('item_id')],
        ['store_id','=',$request->input('store_id')]
        ]
        )->get();

    if($inventory->count()!=1)
    {
         return response()->json(['Error'=>'Model not found'],404);
    }

    $remaining = $inventory->get(0)->count;

    if($request->input('count') > $remaining)
    {
        return response()->json(['Error'=>'Request item count should be less than in the selected store!'],422);
    }


    // get user id bu auth. but for now i will make it static to complete first version of api 
    testing
    $request['user_id'] = 1;
    $newModel = Kittrans::create($request->all());

    $remaining = $remaining - $request->input('count');
    Inventory::where('id',$inventory->get(0)->id)->update(array('count' => $remaining));

    return response()->json($newModel,200);

}

/**
 * Display the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function show(Kittrans $kittrans)
{
    //
    return response()->json($kittrans,200);
}

/**
 * Show the form for editing the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function edit($id)
{
    //
}

/**
 * Update the specified resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function update(Request $request, Kittrans $kittrans)
{

    $kittrans->fill($request->only([
        'item_id',
        'kmo_id',
        'count'
        ]));

    if($kittrans->isClean())
    {
        return response()->json(['Error'=>'You should make some changes in your values to update'],422);
    }

    $kittrans->save();
    return response()->json($kittrans,200);
}

/**
 * Remove the specified resource from storage.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function destroy(Kittrans $kittrans)
{
    //

 $kittrans->delete();

 return response()->json($kittrans,200);
}
}

and route/api.php as following :

Route::resource('kittrans','Kittrans\KittransController',['except'=>['index']]);

when i make a request to update the object in database the problem is a new model will be inserted into the table with $kittrans->save() method!!

why like this issue happening?

my request from postman look like this :

URL : myApp.test/kittrans/5003

method : put,patch

Content-type : application/x-www-form-urlencoded

data : item_id,kmo_id,count

Also i have added dd($kittrans); before save() method and i got the following :

Kittrans {#345
#fillable: array:4 [
0 => "count"
1 => "kmo_id"
2 => "item_id"
3 => "user_id"
]
#connection: null
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: false
+wasRecentlyCreated: false
#attributes: array:3 [
"item_id" => "1"
"kmo_id" => "1"
"count" => "7"
]
#original: []
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [
0 => "*"
]
}

why save method are going to create a new instance of model in db? i have implement update method in all other controllers and everything is ok, but for this controller i don't understand where is the problem?

The parameter for your controller method for the model binding isn't named correctly.

Your route parameter is kittran not kittrans ; resource routing will use the singular name of the resource for the route parameter. You have to match that name for the binding:

public function update(Request $request, Kittrans $kittran)

Without that match you are just getting a new model instance injected instead of a model binding happening.

You can run the route:list command to see how your routes are being defined:

php artisan route:list

"Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name." - Laravel 6.x Docs - Routing - Route Model Bindings - Implicit Binding

"By default, Route::resource will create the route parameters for your resource routes based on the "singularized" version of the resource name." - Laravel 6.x Docs - Controllers - Resource Controllers - Naming Resource Route Parameters

If you want to override this behavior, for this resource, and use kittrans as the parameter name you can also do that, then you wouldn't need to change your controller method's signature:

Route::resource('kittrans', 'Kittrans\KittransController', [
    'except'=> ['index'],
    'parameters' => ['kittrans' => 'kittrans'],
]);

I believe you model binding is not correct, when you model binding is wrong the Kittrans object will be empty and not saved to the db, when you fill and save it will save a new object. To solve your wrong model binding add this to the RouteServiceProvider.php .

use App\Kittrans;

public function boot()
{
    parent::boot();

    Route::model('kittrans', Kittrans::class);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM