简体   繁体   中英

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

I guess you look for 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 .

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.

You will find it in documentation.

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

I think what you might be looking for is eager-load-constraints . This will let you apply a custom query to an ORM relation. 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. Eloquent's eager-loading uses IN statements in independent queries, not 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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