Laravel check if related model exists

匿名 (未验证) 提交于 2019-12-03 02:11:02

问题:

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.

回答1:

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 


回答2:

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() or count() methods directly from a relation object:

$model->relation()->exists(); // bool: true if there is at least one row $model->relation()->count(); // int: number of related rows 

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() or count($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, using exists doesn't need to pull model data either.

Both exists() and count() work on all relation types I've tried, so at least belongsTo, hasOne, hasMany, and belongsToMany.



回答3:

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



回答4:

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.



回答5:

You can use the relationLoaded method on the model object. This saved my bacon so hopefully it helps someone else. I was given this suggestion when I asked the same question on Laracasts.



回答6:

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, a Model or Null. And in Php 7.1 count(null) will throw an error.

So, to check if the relation exist you can use:

For relationships single: For example hasOne and belongsTo

if(!is_null($model->relation)) {    .... } 

For relationships multiple: For Example: hasMany and belongsToMany

if ($model->relation->isNotEmpty()) {    .... } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!