php Laravel 检查相关模型是否存在
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23910553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel Check If Related Model Exists
提问by Tom Macdonald
I have an Eloquent model which has a related model:
我有一个 Eloquent 模型,它有一个相关模型:
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.
<related_model_exists>
我要找的代码在哪里。
回答by Jarek Tkaczyk
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:
在php 7.2+ 中,您不能count
在关系对象上使用,因此没有适用于所有关系的万能方法。使用查询方法代替下面提供的@tremby:
$model->relation()->exists()
generic solution working on all the relation types (pre php 7.2):
适用于所有关系类型的通用解决方案(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
.
这将适用于每个关系,因为动态属性返回Model
或Collection
。两者都实现ArrayAccess
.
So it goes like this:
所以它是这样的:
single relations:hasOne
/ belongsTo
/ morphTo
/ morphOne
单一的关系: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
对多关系: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
回答by tremby
A Relation objectpasses 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 itsunderlying query Builder.
甲Relation对象穿过一个未知的方法调用口才查询生成器,其被设置为仅选择相关对象。该 Builder 又将未知方法调用传递给其底层查询 Builder。
This means you can use the exists()
or count()
methods directly from a relation object:
这意味着您可以直接从关系对象使用exists()
或count()
方法:
$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).
请注意relation
:后面的括号->relation()
是一个函数调用(获取关系对象),而不是->relation
Laravel 为您设置的魔法属性 getter(获取相关对象/对象)。
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.
count
在关系对象上使用该方法(即使用括号)将比执行$model->relation->count()
or count($model->relation)
(除非该关系已经预先加载)快得多,因为它运行计数查询而不是拉取任何相关对象的所有数据从数据库中,只是为了计算它们。同样, usingexists
也不需要拉模型数据。
Both exists()
and count()
work on all relation types I've tried, so at least belongsTo
, hasOne
, hasMany
, and belongsToMany
.
无论exists()
和count()
工作在我已经尝试了所有关系类型,所以至少belongsTo
,hasOne
,hasMany
,和belongsToMany
。
回答by Hafez Divandari
I prefer to use exists
method:
我更喜欢使用exists
方法:
RepairItem::find($id)->option()->exists()
RepairItem::find($id)->option()->exists()
to check if related model exists or not. It's working fine on Laravel 5.2
检查相关模型是否存在。它在 Laravel 5.2 上运行良好
回答by Hemerson Varela
After Php 7.1, The accepted answer won't work for all types of relationships.
在Php 7.1 之后,接受的答案不适用于所有类型的关系。
Because depending of type the relationship, Eloquent will return a Collection
, a Model
or Null
. And in Php 7.1count(null)
will throw an error
.
因为根据关系的类型,Eloquent 将返回 a Collection
、 aModel
或Null
。而在PHP 7.1 中count(null)
会抛出一个error
.
So, to check if the relation exist you can use:
因此,要检查关系是否存在,您可以使用:
For relationships single: For example hasOne
and belongsTo
对于单身关系:例如hasOne
和belongsTo
if(!is_null($model->relation)) {
....
}
For relationships multiple: For Example: hasMany
and belongsToMany
对于多个关系:例如:hasMany
和belongsToMany
if ($model->relation->isNotEmpty()) {
....
}
回答by Dave Stewart
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.
不确定这是否在 Laravel 5 中发生了变化,但接受的答案 usingcount($data->$relation)
对我不起作用,因为访问关系属性的行为导致它被加载。
In the end, a straightforward isset($data->$relation)
did the trick for me.
最后,一个简单isset($data->$relation)
的方法对我有用。
回答by Anthony
You can use the relationLoadedmethod on the model object. This saved my bacon so hopefully it helps someone else. I was given this suggestionwhen I asked the same question on Laracasts.
您可以在模型对象上使用relationLoaded方法。这救了我的培根,所以希望它能帮助别人。我给出这个建议的时候,我问上Laracasts同样的问题。
回答by Adam
As Hemerson Varela already said in Php 7.1 count(null)
will throw an error
and hasOne
returns null
if no row exists. Since you have a hasOne
relation I would use the empty
method to check:
正如 Hemerson Varela 在 Php 7.1 中已经说过的那样,如果不存在行,count(null)
将抛出一个error
并hasOne
返回null
。既然你有hasOne
关系,我会用这个empty
方法来检查:
$model = RepairItem::find($id);
if (!empty($temp = $request->input('option'))) {
$option = $model->option;
if(empty($option)){
$option = $model->option()->create();
}
$option->someAttribute = temp;
$option->save();
};
But this is superfluous. There is no need to check if the relation exists, to determine if you should do an update
or a create
call. Simply use the updateOrCreatemethod. This is equivalent to the above:
但这是多余的。无需检查关系是否存在,以确定您是否应该拨打电话update
或create
拨打电话。只需使用updateOrCreate方法。这相当于上面的:
$model = RepairItem::find($id);
if (!empty($temp = $request->input('option'))) {
$model->option()
->updateOrCreate(['repair_item_id' => $model->id],
['option' => $temp]);
}
回答by raphjutras
I had to completely refactor my code when I updated my PHP version to 7.2+ because of bad usage of the count($x) function. This is a real pain and its also extremely scary as there are hundreds usages, in different scenarios and there is no one rules fits all..
由于 count($x) 函数使用不当,当我将 PHP 版本更新到 7.2+ 时,我不得不完全重构我的代码。这是一个真正的痛苦,它也非常可怕,因为在不同的场景中有数百种用法,并且没有一个规则适合所有。
Rules I followed to refactor everything, examples:
我遵循的规则来重构一切,例如:
$x = Auth::user()->posts->find(6);(check if user has a post id=6 using ->find())
$x = Auth::user()->posts->find(6); (使用 ->find() 检查用户是否有帖子 id=6)
[FAILS] if(count($x)) { return 'Found'; }
[GOOD] if($x) { return 'Found'; }
$x = Auth::user()->profile->departments;(check if profile has some departments, there can have many departments)
$x = Auth::user()->profile->departments; (检查profile是否有一些部门,可以有很多部门)
[FAILS] if(count($x)) { return 'Found'; }
[GOOD] if($x->count()) { return 'Found'; }
$x = Auth::user()->profile->get();(check if user has a profile after using a ->get())
$x = Auth::user()->profile->get(); (在使用 ->get() 后检查用户是否有个人资料)
[FAILS] if(count($x)) { return 'Found'; }
[GOOD] if($x->count()) { return 'Found'; }
Hopes this can help, even 5 years after the question has been asked, this stackoverflow post has helped me a lot!
希望这能有所帮助,即使在提出问题 5 年后,这篇 stackoverflow 帖子也对我有很大帮助!