我在laravel RESTful API构建中遇到问题,
我有以下控制器
<?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);
}
}
和route / api.php如下:
Route::resource('kittrans','Kittrans\KittransController',['except'=>['index']]);
当我请求更新数据库中的对象时,问题是将使用$ kittrans-> save()方法将新模型插入表中!
为什么会发生此问题?
我的邮递员请求看起来像这样:
URL:myApp.test / kittrans / 5003
方法:放置,修补
内容类型:应用程序/ x-www-form-urlencoded
数据:item_id,kmo_id,计数
还我添加了在save()方法之前,dd($kittrans);
和我得到以下内容:
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 => "*"
]
}
为什么save方法将在db中创建模型的新实例?我在所有其他控制器中都实现了更新方法,一切正常,但是对于此控制器,我不知道问题出在哪里?
没有正确命名用于模型绑定的控制器方法的参数。
您的路线参数是kittran
而不是kittrans
;资源路由将使用资源的唯一名称作为route参数。您必须为绑定匹配该名称:
public function update(Request $request, Kittrans $kittran)
没有该匹配项,您只是注入一个新的模型实例,而不是发生模型绑定。
您可以运行route:list
命令来查看路由的定义方式:
php artisan route:list
“ Laravel自动解析在路由或控制器操作中定义的口才模型,这些操作的类型提示变量名称与路由段名称匹配。” -Laravel 6.x Docs - Routing - Route Model Bindings - Implicit Binding
“默认情况下,
Route::resource
将基于资源名称的”单数“版本为您的资源路由创建路由参数。” -Laravel 6.x Docs - Controllers - Resource Controllers - Naming Resource Route Parameters
我相信您的模型绑定不正确,当您的模型绑定错误时,Kittrans对象将为空并且不会保存到db,当您填充并保存它时将保存一个新对象。要解决错误的模型绑定,请将其添加到RouteServiceProvider.php
。
use App\Kittrans;
public function boot()
{
parent::boot();
Route::model('kittrans', Kittrans::class);
}