64

I recently started using Eloquent.

When I used PHP Active Record, there was a nice function that checked if a record was loaded from the database or is a new instance. Is there something similar in Eloquent that I could use?

By new I mean:

$article = new Article;

whereas one from the database would be

$article = Article::find(1);
Rubens Mariuzzo
  • 28,358
  • 27
  • 121
  • 148
Craig Ward
  • 2,425
  • 5
  • 33
  • 51

5 Answers5

129

All laravel models have a ->exists property.

More specifically if the model is either loaded from the database, or has been saved to the database since being created the exists property will be true; Otherwise it will be false.

If you wish to know if the model has been modified since being grabbed from the database, or simply not saved at all (aka if it needs saving) then you can use the ->isDirty() function.

The Laravel API is a useful place for this kind of information: http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Model.html#method_isDirty and often sheds far more light than the default documentation.

Rahil Wazir
  • 10,007
  • 11
  • 42
  • 64
Hailwood
  • 89,623
  • 107
  • 270
  • 423
98

Your model object has an attribute exactly designed for that. It's wasRecentlyCreated :

$item = Item::firstOrCreate(['title' => 'Example Item']);

if ($item->wasRecentlyCreated === true) {
    // item wasn't found and have been created in the database
} else {
    // item was found and returned from the database
}

For more clarification between the way exists variable works vs wasRecentlyCreated variable (copied from the comment by CJ Dennis below)

 /* Creating a model */ 
 $my_model = new MyModel; 
 $my_model->exists === false; 
 $my_model->wasRecentlyCreated === false; 
 $my_model->save(); 
 $my_model->exists === true; 
 $my_model->wasRecentlyCreated === true;

As opposed to if a model was loaded from a previous request:

/* Loading a Model */ 
$my_model = MyModel::first(); 
$my_model->exists === true; 
$my_model->wasRecentlyCreated === false;
ftrotter
  • 3,066
  • 2
  • 38
  • 52
Didier Sampaolo
  • 2,566
  • 4
  • 24
  • 34
  • 6
    `wasRecentlyCreated ` indicates if the model was inserted during the current request lifecycle. So even if the record was missing from the DB, it will only return `true` after it is saved. – Jack Apr 11 '18 at 20:33
  • 1
    `/* Creating a model */ $my_model = new MyModel; $my_model->exists === false; $my_model->wasRecentlyCreated === false; $my_model->save(); $my_model->exists === true; $my_model->wasRecentlyCreated === true; /* Loading a Model */ $my_model = MyModel::first(); $my_model->exists === true; $my_model->wasRecentlyCreated === false;` – CJ Dennis Jul 30 '19 at 01:51
  • It returns `false` if you create a record then query again for that newly created `Item::firstOrCreate(['title' => 'Example Item']);` then, `Item::where(['title' => 'Example Item'])->first()->wasRecentlyCreated` this will return `false`. Remember to get the return value of the create methods. But the problems is, when working with creating related models and querying the newly created models. – Julio Motol Jul 06 '20 at 02:24
1

We can use $appends on model if you will use it many times.. for example to check if the newly created comment is edited after created.

class Comment extends Model
{
     protected $appends = ['is_edited'];

     public function getIsEditedAttribute()
     {
          return $this->attributes['is_edited'] = ($this->created_at != $this->updated_at) ? true : false;
     }
}

You can use it like

$comment = Comment::findOrFail(1);

if($comment->is_edited){
      // write your logic here
}
shakee93
  • 4,976
  • 2
  • 28
  • 32
0
$article = new Article;
var_dump($article->id); == null

$article = Article::find(1);
var_dump($article->id); == string(1) "1"

so

if ($article->id) {
     // I am existing
} else {
    // I am new
}
Wizzard
  • 12,582
  • 22
  • 68
  • 101
-3

I am using Laravel Eloquent's updateOrCreate() method to create or update records when importing from a CSV file.

$product = $this->updateOrCreate($attributes, $values);

I wanted to count the amount of newly created records and updated records. Since the updateOrCreate() method saves the record to the database upon creation, $product->exists will always return true.

An alternative is to compare the created_at and updated_at timestamps of the model with the current time:

if($product->created_at == Carbon::now())
            $created++;
        elseif ($product->updated_at == Carbon::now())
            $updated++;
HPage
  • 1,412
  • 20
  • 27
  • If in the same request, then the timestamp lacks enough precision to know if the record was just created – Snapey Feb 11 '21 at 14:29