Laravel Check If Related Model Exists

Tom Macdonald picture Tom Macdonald · May 28, 2014 · Viewed 153.3k times · Source

I have an Eloquent model which has a related model:

public function option() {
    return $this->hasOne('RepairOption', 'repair_item_id');
}

public function setOptionArrayAttribute($values)
{
    $this->option->update($values);
}

When I create the model, it does not necessarily have a related model. When I update it, I might add an option, or not.

So I need to check if the related model exists, to either update it, or create it, respectively:

$model = RepairItem::find($id);
if (Input::has('option')) {
    if (<related_model_exists>) {
        $option = new RepairOption(Input::get('option'));
        $option->repairItem()->associate($model);
        $option->save();
        $model->fill(Input::except('option');
    } else {
       $model->update(Input::all());
    }
};

Where <related_model_exists> is the code I am looking for.

Answer

Jarek Tkaczyk picture Jarek Tkaczyk · May 28, 2014

In php 7.2+ you can't use count on the relation object, so there's no one-fits-all method for all relations. Use query method instead as @tremby provided below:

$model->relation()->exists()

generic solution working on all the relation types (pre php 7.2):

if (count($model->relation))
{
  // exists
}

This will work for every relation since dynamic properties return Model or Collection. Both implement ArrayAccess.

So it goes like this:

single relations: hasOne / belongsTo / morphTo / morphOne

// no related model
$model->relation; // null
count($model->relation); // 0 evaluates to false

// there is one
$model->relation; // Eloquent Model
count($model->relation); // 1 evaluates to true

to-many relations: hasMany / belongsToMany / morphMany / morphToMany / morphedByMany

// no related collection
$model->relation; // Collection with 0 items evaluates to true
count($model->relation); // 0 evaluates to false

// there are related models
$model->relation; // Collection with 1 or more items, evaluates to true as well
count($model->relation); // int > 0 that evaluates to true