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.
I prefer to use
exists
method:RepairItem::find($id)->option()->exists()
to check if related model exists or not. It's working fine on Laravel 5.2
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:generic solution working on all the relation types (pre php 7.2):
This will work for every relation since dynamic properties return
Model
orCollection
. Both implementArrayAccess
.So it goes like this:
single relations:
hasOne
/belongsTo
/morphTo
/morphOne
to-many relations:
hasMany
/belongsToMany
/morphMany
/morphToMany
/morphedByMany
A Relation object passes unknown method calls through to an Eloquent query Builder, which is set up to only select the related objects. That Builder in turn passes unknown method calls through to its underlying query Builder.
This means you can use the
exists()
orcount()
methods directly from a relation object:Note the parentheses after
relation
:->relation()
is a function call (getting the relation object), as opposed to->relation
which a magic property getter set up for you by Laravel (getting the related object/objects).Using the
count
method on the relation object (that is, using the parentheses) will be much faster than doing$model->relation->count()
orcount($model->relation)
(unless the relation has already been eager-loaded) since it runs a count query rather than pulling all of the data for any related objects from the database, just to count them. Likewise, usingexists
doesn't need to pull model data either.Both
exists()
andcount()
work on all relation types I've tried, so at leastbelongsTo
,hasOne
,hasMany
, andbelongsToMany
.Not sure if this has changed in Laravel 5, but the accepted answer using
count($data->$relation)
didn't work for me, as the very act of accessing the relation property caused it to be loaded.In the end, a straightforward
isset($data->$relation)
did the trick for me.As Hemerson Varela already said in Php 7.1
count(null)
will throw anerror
andhasOne
returnsnull
if no row exists. Since you have ahasOne
relation I would use theempty
method to check:After Php 7.1, The accepted answer won't work for all types of relationships.
Because depending of type the relationship, Eloquent will return a
Collection
, aModel
orNull
. And in Php 7.1count(null)
will throw anerror
.So, to check if the relation exist you can use:
For relationships single: For example
hasOne
andbelongsTo
For relationships multiple: For Example:
hasMany
andbelongsToMany