Home > Back-end >  Cannot update with an API request in Laravel
Cannot update with an API request in Laravel

Time:04-25

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.

route:list

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.

  • Related