英文:
Is there a difference when to use with() with an array or a string as parameter?
问题
Version A: $someModel->with('relationMethodA.id,some_field, created_at')
Version B: $someModel->with(['relationMethodA' => fn($q) => $q->select('relationMethodA.id,some_field, created_at')])
两个版本都会产生相同的结果。是否有使用其中一个的原因?
英文:
It was brought to my attention in a code review, instead of:
Version A: $someModel->with('relationMethodA.id,some_field, created_at')
rather use this notation:
Version B $someModel->with(['relationMethodA' => fn($q) => $q->select('relationMethodA.id,some_field, created_at')])
.
I wonder because both give the same result. Are there any reasons to use one or the other?
答案1
得分: 2
当使用急加载时,你所示范的第一个语法应该使用冒号:
$someModel->with('relationMethodA:id,some_field,created_at')
这样只加载三列,与在关系中添加select语句的效果相同,就像你在第二个示例中所做的那样。
请注意,你还可以传递一个相关模型的数组:
$someModel->with(['relationA', 'relationB', 'relationC']);
以及只传递多个参数:
$someModel->with('relationA', 'relationB', 'relationC');
以及嵌套关系:
$someModel->with('relationA.subrelation', 'relationB');
个人建议,始终使用冒号来指定要加载的列,因为这比使用闭包方法更加简洁和可读,尽管闭包方法可以用于添加额外的条件或查询作用域。
英文:
When eager loading, the first syntax you illustrated should use a colon;
$someModel->with('relationMethodA:id,some_field, created_at')
So this loads just three of the columns and is the same as adding a select statement to the relationship, as you did in the second example
Note that you can also pass an array of related models;
$someModel->with(['relationA', 'relationB','relationC']);
as well as just passing multiple parameters
$someModel->with('relationA', 'relationB','relationC');
and nested relations
$someModel->with('relationA.subrelation','relationB');
personally, I would always use the colon to specify the columns to load as this is far more concise and readable than the closure approach, although this can be useful for adding additional conditions or even query scopes.
答案2
得分: 1
As what document said in Constraining Eager Loads
> 有时,您可能希望急切加载关系,同时为急切加载查询指定附加的查询条件。您可以通过将关系数组传递给 with 方法来实现此目标,其中数组键是关系名称,数组值是添加附加约束的闭包:
You can see in the official document example:
use App\Models\User;
use Illuminate\Contracts\Database\Eloquent\Builder;
$users = User::with(['posts' => function (Builder $query) {
$query->where('title', 'like', '%code%');
}])->get();
只有那些标题中包含 code
的帖子会加载到每个用户中。
$someModel->with(['relationMethodA' => fn($q) => $q->select('relationMethodA.id,some_field, created_at')])
这将仅加载关系 "relationMethodA" 的特定列:'relationMethodA.id, some_field, created_at',但是 Version A 将加载所有列。当您不需要关系中的全部数据时,这可能是一个不错的选项。
英文:
As what document said in Constraining Eager Loads
> Sometimes you may wish to eager load a relationship but also specify additional query conditions for the eager loading query. You can accomplish this by passing an array of relationships to the with method where the array key is a relationship name and the array value is a closure that adds additional constraints to the eager loading query:
You can see in the official document example:
use App\Models\User;
use Illuminate\Contracts\Database\Eloquent\Builder;
$users = User::with(['posts' => function (Builder $query) {
$query->where('title', 'like', '%code%');
}])->get();
Only those posts with the word code
in their title will load for each user.
$someModel->with(['relationMethodA' => fn($q) => $q->select('relationMethodA.id,some_field, created_at')])
This will load the relation "relationMethodA" with this specific columns only:
'relationMethodA.id,some_field, created_at', However Version A will load all columns. This might be a good option when you don't need whole data in your relations.
答案3
得分: 1
好的,以下是翻译好的部分:
"确实,两个查询都返回相同的结果,但有非常轻微且可以忽略的性能差异,使得版本A更快。但是,版本B将允许您在查询中添加更多复杂性。"
英文:
Well, Indeed both queries return the same result but there's very slight and neglible perfromance measure which makes Version A to be faster.
However Version B will allow you to add more complexity in the query.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论