I try to update a record with an API request from a Vue SPA and it fails Here are the relevant parts of my application
The migration of the relevant table
public function up()
{
Schema::create('user_preferences', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(\App\Models\User::class,'user_id');
$table->json('brands_fermentable');
$table->timestamps();
});
}
The model
class UserPreferences extends Model
{
use HasFactory;
protected $casts = [
'brands_fermentable' => 'array'
];
protected $fillable=[
'user_id',
'brands_fermentable'
];
}
The resource
class UserPreferencesResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'user_id'=>$this->user_id,
'brands_fermentable'=>$this->brands_fermentable,
'created_at' => (new \DateTime($this->created_at))->format('Y-m-d H:i:s'),
'updated_at' => (new \DateTime($this->updated_at))->format('Y-m-d H:i:s')
];
}
}
The requests
class UpdateUserPreferencesRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
"id"=>'required|integer',
"user_id" => 'required|integer',
"brands_fermentable"=>'required|array'
];
}
The controller methods
public function update(UpdateUserPreferencesRequest $request, UserPreferences $userPreferences)
{
$userPreferences->update(
$request->validated());
return (new UserPreferencesResource($userPreferences));
}
public function store(StoreUserPreferencesRequest $request)
{
$data = $request->validated();
$data['user_id'] = Auth::user()->id ;
$result = UserPreferences::create( $data);
return new UserPreferencesResource($result);
}
The requests I made
First request is a post (It works)
POST
Request payload
{
"brands_fermentable": [
1,
3
],
"id": null,
"user_id": null
}
Request response
{
"data": {
"id": 53,
"user_id": 1,
"brands_fermentable": [
1,
3
],
"created_at": "2022-04-22 10:40:25",
"updated_at": "2022-04-22 10:40:25"
}
}
Second request is a put (it fails)
PUT
Request payload
{
"brands_fermentable": [
1,
3,
2
],
"id": 53,
"user_id": 1
}
Request response
{
"data": {
"id": null,
"user_id": null,
"brands_fermentable": null,
"created_at": "2022-04-22 10:40:31",
"updated_at": "2022-04-22 10:40:31"
}
}
I cannot understand what is wrong. I did similar things with other controllers with success. The only difference here being the array that is stored as brands_fermentable. I need help. Thanks in advance
EDIT AFTER FIRST COMMENT
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', function (Request $request) {
return $request->user();
});
Route::delete('/logout', [AuthController::class, 'logout']);
Route::post('/fermentableBoth',[FermentableBothController::class,'store']);
Route::put('/fermentableBoth/{fermentable}',[FermentableBothController::class,'update']);
Route::resource('inventoryFermentable', InventoryFermentableController::class);
Route::resource('fermentable', FermentableController::class);
Route::resource('fermentableBrand', FermentableBrandController::class);
Route::resource('userPreferences',UserPreferencesController::class);
});
CodePudding user response:
Based on your route resource and update() method signature, you need to use the singular variable name in your route model binding (notice the removal of s
in the variable.
Laravel's route model binding requires the exact variable name as the route definition, which is singular.
public function update(UpdateUserPreferencesRequest $request, UserPreferences $userPreference)
As a suggestion, it is good practice to name your models as singular as well (ie: UserPreference
). A model is 1 item.