初めてのLaravel 5.6 : (20) Scope

前回で、Article に記事を追加したり、追加時のエラーチェックが行える用になりました。記事のデータも増えてきたので、記事一覧を少し修正したいと思います。

現在、記事一覧には2つの問題があります。1つは新しい記事が下の方に表示されてしまうこと、もう一つは、公開日(published_at)を将来の日付に設定した場合でも表示されてしまうことです。今回はこの2点を修正します。


記事のソート

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();  これでもOKです
        $articles = Article::latest('published_at')->latest('created_at')->get();

        return view('articles.index', compact('articles'));
    }
}

all() を使って記事を全件取得していた部分を、latest()->get() に変更して、作成日の降順に記事をソートするよう修正しました。
orderBy()->get() を使っても同様のことが出来ます。


where

次に公開日が現在時刻以前の記事だけを取得するように修正します。

<?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'));
    }
}

where をメソッドチェインに追加しました。


scope

「公開日が現在時刻以前の記事」という条件は何度も使いそうな気がするので、Eloquent のScope 機能を使って、修正します。

まずは、モデルに scope メソッドを追加します。scope を定義するにはメソッドの頭に’scope’を付けます。

<?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());
    }

    // ...
}

次にコントローラで scope を使用するよう修正します。
where を 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'));
    }
}

スコープにしたことにより、published() の再利用も簡単ですし、可読性も上がりました。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中