Query with Quality - [Local Query Scope and Global Query Scope]
Global Query Scope :
let's we have a common query for user , post , comment etc model , like view newest data first . now we writing query with sorting function to get newest data first. Global query scope in laravel provide e common place where we write the sorting query in a function and define to model data should be sorted in model boot function .
example: defining global scope
<?php
namespace App\Scopes ;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class LatestScope implements Scope{
public function apply(Builder $builder , Model $model){
$builder->orderBy('created_at','desc') ;
}
}
adding LatestScope to BlogPost model
public static function boot(){
parent::boot() ;
static::addGlobalScope(new LatestScope) ;
}
Local Query Scope
we want reuse same query for a specific model then we write scope function , the function return query we can reuse same query in local specific model.
BlogPost model
public function comments(){
return $this->hasMany(Comment::class) ;
// return $this->hasMany(Comment::class)->latest() ;
}
public function user(){
return $this->belongsTo(User::class) ;
}
//latest()
public function scopeLtst(Builder $query){
return $query->orderBy('created_at','desc');
}
public function scopeMostCommented(Builder $query){
return $query->withCount('comments')->orderBy('comments_count','desc');
}
User model :
public function blog_post()
{
return $this->hasMany(BlogPost::class);
}
public function scopeWithMostBlogPost(Builder $builder)
{
return $builder->withCount('blog_post')->orderBy('blog_post_count', 'desc');
}
public function scopeWithMostBlogPostLastMonth(Builder $builder)
{
return $builder->withCount(['blog_post' => function (Builder $builder) {
$builder->whereBetween('created_at', [now()->subMonths(1), now()]);
}])->having('blog_post_count', '>=', 2)
->orderBy('blog_post_count', 'desc');
}
querying from BlogPostController
public function list()
{
$posts = BlogPost::ltst()->withCount('comments')->get();
$most_commented = BlogPost::mostCommented()->take(5)->get() ;
$most_active = User::withMostBlogPost()->take(5)->get() ;
$most_active_last_month = User::withMostBlogPostLastMonth()->take(5)->get() ;
return view('blog.list', [
'posts' => $posts,
'most_commented' => $most_commented,
'most_active' => $most_active,
'most_active_last_month' => $most_active_last_month
]);
}