'UpdateOrCreate always updates first record on update and fails on create

I've created an application on Laravel 8.x and I'm creating simple CRUD operations, in which I used UpdateOrCreate in save(Request $request) function. This save function is being used for both create and update the form. When update is performed on a record, it works very well as intended but when a new record is created, it gives following error on save function:

Illuminate\Database\QueryException

SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'field list' (SQL: insert into 
`todolist` (`0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `id`, `todo_name`, `todo_description`, 
`user_id`, `updated_at`, `created_at`) values (id, todo_name, todo_description, user_id, 
is_active, is_deleted, created_at, updated_at, ?, test123, test123, 1, 2022-04-16 07:41:13, 
2022-04-16 07:41:13))

http://127.0.0.1:8000/to-do-list-save

Following is the model code:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ToDoList extends Model
{
    use HasFactory;
    protected $table = 'todolist';
    protected $primaryKey = 'id';
    public $incrementing = true;
    protected $attributes = [
        'id','todo_name','todo_description' ,'user_id', 'is_active', 'is_deleted','created_at', 'updated_at',
    ];
    protected $guarded = [];
}

Here are the controller functions:

public function view($id){
    $model = ToDoList::where('id',$id)->get();
    return view('todoview', ['model'=>$model]);        
}
public function create(){
    $model = new ToDoList();
    return view('todoform',['model'=>$model]);        
}
public function update($id){
    $model = ToDoList::where('id',$id)->get();
    return view('todoform', ['model'=>$model]);        
}
public function save(Request $request)
{
    $todosave = ToDoList::updateOrCreate([
        //Add unique field combo to match here
        'id'=>$request->get('id'),
    ],[
        'todo_name'     => $request->get('todo_name'),
        'todo_description' => $request->get('todo_description'),
        'user_id' => Auth::user()->id,
    ]);
    return redirect()->route('todolistview', ['id' => $todosave->id]);
}

What am I doing wrong or missing? Thanks in Advance!!!



Solution 1:[1]

The model is missing Mass Assignment that is achieved in laravel by $fillable array. There is no need of $guarded and $attributes arrays:

class ToDoList extends Model
{
    use HasFactory;
    protected $table = 'todolist';
    protected $primaryKey = 'id';
    public $incrementing = true;
    protected $fillable= [
        'id','todo_name','todo_description' ,'user_id', 'is_active', 'is_deleted','created_at', 'updated_at',
    ];
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ramisha Mukhtar