简体   繁体   English

相关模型雄辩的Laravel内部的自定义查询

[英]Custom query inside related model eloquent laravel

I've been looking for the correct way to achieve the following. 我一直在寻找实现以下目标的正确方法。

  • Retrieve a collection of models and their relations 检索模型及其关系的集合
  • For a given relationship adjust it to return the values defined by a custom query 对于给定的关系,调整它以返回自定义查询定义的值

So for example, model users is linked to an archived statistics table. 因此,例如,模型用户链接到存档的统计表。 However these statistics need to be summed with various sources of data in other models which aren't easily related through eloquents ORM 但是,这些统计数据需要与其他模型中的各种数据源进行汇总,而这些数据源很难通过雄辩的ORM进行关联

I guess you look for SCOPES: 我想您正在寻找SCOPES:

Scopes allow you to define common sets of constraints that you may easily re-use throughout your application. 范围使您可以定义常见的约束集,可以轻松地在整个应用程序中重复使用这些约束。 For example, you may need to frequently retrieve all users that are considered "popular". 例如,您可能需要经常检索所有被认为“受欢迎”的用户。 To define a scope, prefix an Eloquent model method with scope . 要定义作用域,请在Eloquent模型方法前加上scope

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Scope a query to only include popular users.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopePopular($query)
    {
        return $query->where('votes', '>', 100);
    }

    /**
     * Scope a query to only include active users.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeActive($query)
    {
        return $query->where('active', 1);
    }
}

Once the scope has been defined, you may call the scope methods when querying the model. 定义范围后,可以在查询模型时调用范围方法。 However, you should not include the scope prefix when calling the method. 但是,在调用方法时,不应包括范围前缀。 You can even chain calls to various scopes, for example: 您甚至可以将调用链接到各种范围,例如:

$users = App\User::popular()->active()->orderBy('created_at')->get();

ometimes you may wish to define a scope that accepts parameters. 有时您可能希望定义一个接受参数的范围。 To get started, just add your additional parameters to your scope. 首先,只需将其他参数添加到您的范围。 Scope parameters should be defined after the $query parameter. 范围参数应在$ query参数之后定义。

You will find it in documentation. 您可以在文档中找到它。

More: https://laravel.com/docs/5.6/eloquent#local-scopes 更多: https//laravel.com/docs/5.6/eloquent#local-scopes

I think what you might be looking for is eager-load-constraints . 我认为您可能正在寻找的是eager-load-constraints This will let you apply a custom query to an ORM relation. 这将使您可以将自定义查询应用于ORM关系。 But you mentioned something in there that, if I understand you right, may throw a wrench in that otherwise simple approach. 但是您在其中提到了一些内容,如果我理解正确的话,可能会以其他方式让您费劲。

You said there are statistics that need to derived by summing up values from multiple models. 您说有些统计数据需要通过汇总多个模型的值来得出。 If you're goal is to actually perform the SUM SQL function, or for that matter, any aggregate, there are some caveats. 如果您的目标是实际执行SUM SQL函数,或者就此而言,任何汇总,请注意以下几点。 Eloquent's eager-loading uses IN statements in independent queries, not JOINs . Eloquent的热切加载在独立查询中使用IN语句,而不是JOINs So if you're performing the aggregate on a relation-of-a-relation, it's going to sum up everything and not necessarily group those operations per immediate-parent the way you'd expect. 因此,如果您要在一个关系关系上执行汇总,它将对所有内容进行汇总,而不必按照您期望的方式对每个直接父级将这些操作分组。

The other thing is, if you're trying to perform this SUM operation on values that span multiple tables, on relation has no direct visibility on another, and you're going to have to use the join() method. 另一件事是,如果您试图对跨越多个表的值执行此SUM操作,则关系在另一个表上没有直接可见性,因此您将不得不使用join()方法。 That's going to take you into the Query-Builder and out of the Eloquent world, and therefore away from any benefit your Model classes might have offered. 这将带您进入Query-Builder,并脱离了Eloquent的世界,因此没有Model类可能提供的任何好处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM