mysqllaravel-5modelfillable

Laravel 5 insert works without $fillable


I have a Laravel application made by someone else.

In the controller I have this:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Result;

class StoreInDB extends Controller
{
    function store($uuid, $session){
        // Insert data
        $r = new Result;
        if($r->updateOrInsert(['user_id' => $uuid], ['user_id' => $uuid, 'answers' => $session])){
            return true;
        }
        else{
            return false;
        }
    }
}

In the Model Result I have this:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Result extends Model
{
    //
}

Why does it work? There is no $fillable to tell which column can be used to insert.

Datas are inserted. But why? The only issue I have is that created_at and updated_at are null.


Solution

  • updateOrInsert uses the query builder and not eloquent, therefore it wont trigger model events or respect the guarded or fillable properties and won't populate the created_at and updated_at columns.

    If you want to use the mentioned eloquent features you should use updateOrCreate.

    Something like this:

    public function store($uuid, $session)
    {
        if (null === Result::updateOrCreate(['user_id' => $uuid], ['answers' => $session])) {
            return false;
        }
    
        return true;
    }
    

    Note that updateOrCreate returns a model instance and updateOrInsert returns a boolean.

    updateOrCreate:

    Occasionally, you may need to update an existing model or create a new model if no matching model exists. Like the firstOrCreate method, the updateOrCreate method persists the model, so there's no need to manually call the save method.

    In the example below, if a flight exists with a departure location of Oakland and a destination location of San Diego, its price and discounted columns will be updated. If no such flight exists, a new flight will be created which has the attributes resulting from merging the first argument array with the second argument array:

    $flight = Flight::updateOrCreate(
        ['departure' => 'Oakland', 'destination' => 'San Diego'],
        ['price' => 99, 'discounted' => 1]
    );
    

    updateOrInsert:

    Sometimes you may want to update an existing record in the database or create it if no matching record exists. In this scenario, the updateOrInsert method may be used. The updateOrInsert method accepts two arguments: an array of conditions by which to find the record, and an array of column and value pairs indicating the columns to be updated.

    The updateOrInsert method will attempt to locate a matching database record using the first argument's column and value pairs. If the record exists, it will be updated with the values in the second argument. If the record can not be found, a new record will be inserted with the merged attributes of both arguments:

    DB::table('users')
        ->updateOrInsert(
            ['email' => 'john@example.com', 'name' => 'John'],
            ['votes' => '2']
        );