Tự học Laravel: (20) SCOPE

Last time , you can add articles to Article and check for errors when adding. Article data has also increased, so I would like to correct the article list a bit.

Currently, there are two issues with article listings. One is that a new article is displayed at the bottom, and the other is that it is displayed even if the published date (published_at) is set to a future date. This time we fix these two points.

ARTICLE SORT

Modify ArticlesController.php

<?php
//app/Http/Controllers/ArticlesController.php
namespace App\Http\Controllers;
 
// ...
class ArticlesController extends Controller {
 
    public function index() {
        // $articles = Article::all();  
        // $articles = Article::orderBy('published_at', 'desc')->orderBy('created_at', 'desc')->get();  
        $articles = Article::latest('published_at')->latest('created_at')->get();
 
        return view('articles.index', compact('articles'));
    }
}

The part where all articles were retrieved using all() was changed to latest()->get(), and the articles were sorted in descending order of creation date.
You can do the same with orderBy()->get().

WHERE

Next, fix it so that only the articles whose publication date is before the current time will be retrieved.

<?php
namespace App\Http\Controllers;
// app/Http/Controllers/ArticlesController.php
 
// ...
use Carbon\Carbon;
 
class ArticlesController extends Controller {
 
    public function index() {
        $articles = Article::latest('published_at')->latest('created_at')
            ->where('published_at', '<=', Carbon::now())
            ->get();
 
        return view('articles.index', compact('articles'));
    }
}

Added where to the method chain.

SCOPE

The condition “articles published before the current time” seems to be used many times, so I use Eloquent’s Scope function to fix it.

First, add the scope method to your model. To define a scope, put ‘scope’ at the beginning of the method.

<?php
// app/Article.php
namespace App;
 
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
 
class Article extends Model {
    // ...
 
    //  published scope
    public function scopePublished($query) {
        $query->where('published_at', '<=', Carbon::now());
    } 
    // ...
}

Next, modify the controller to use scope. 
Replace where with scope.

<?php
// app/Http/Controllers/ArticlesController.php
namespace App\Http\Controllers;
 
// ...
use Carbon\Carbon;
 
class ArticlesController extends Controller {
 
    public function index() {
        $articles = Article::latest('published_at')->latest('created_at')
            ->published()
            ->get();
 
        return view('articles.index', compact('articles'));
    }
}

The scope makes it easy to reuse published() and improves readability.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.