カテゴリー
Linux

【Laravel 5.5】WordPress の DB を使ってお勉強。投稿に紐づく投稿者情報をパッと取得する

学んだこと

  • aaa テーブルに xxx_id カラムがある場合、 xxx を取得するには belongsTo() を使う。 aaa モデルクラスで次のように使う。なお、 xxx テーブルのプライマーキーは id とする。
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Aaa extends Model
{
    public function xxx(): BelongsTo
    {
        return $this->belongsTo('App¥Xxx', 'xxx_id', 'id');
    }
}
  • リレーションへはメソッドとしてもアクセスできるが、プロパティとしてアクセスでき、そのほうが性能が有利になる。なぜなら、実際にアクセスされた時にだけそのリレーションのデータはロードされる (遅延ロード) ため。
  • Eagerロード で N + 1 問題を回避できる。今回の例では、投稿一覧の取得で 1 回、取得できた 5 件の投稿の各ユーザを取得するのにさらに 5 回、 SQL が発行されていた。それを、 Eager ロードすることによって、 2 回の SQL 発行へ減らすことができた。

コード。投稿から紐付く投稿者を習得して表示する

$ git diff
diff --git a/app/Models/Wp/Post.php b/app/Models/Wp/Post.php
index bb7c287..c65bbaf 100644
--- a/app/Models/Wp/Post.php
+++ b/app/Models/Wp/Post.php
@@ -4,6 +4,7 @@ namespace App\Models\Wp;

 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;

 /**
  * @property int $ID
@@ -65,6 +66,15 @@ class Post extends Model
      */
     public $timestamps = false;

+    /**
+     * この投稿の投稿者を取得します。
+     * @return BelongsTo
+     */
+    public function user(): BelongsTo
+    {
+        return $this->belongsTo('App\Models\WP\User', 'post_author', 'ID');
+    }
+
     /**
      * 投稿種別が投稿のレコードに限定するクエリスコープです。
      * @param Builder $query
diff --git a/resources/views/admin/posts/index.blade.php b/resources/views/admin/posts/index.blade.php
index 13bb7eb..06159c9 100644
--- a/resources/views/admin/posts/index.blade.php
+++ b/resources/views/admin/posts/index.blade.php
@@ -27,7 +27,7 @@
         <tr>
           <th scope="row">{{ $post->ID }}</th>
           <td>{{ $post->post_title }} - {{ $post->post_status_description }}</td>
-          <td>{{ $post->post_author }}</td>
+          <td>{{ $post->user()->first()->display_name }}</td>
           <td>categories</td>
           <td>tags</td>
           <td>{{ $post->comment_count }}</td>
$

コード。 Eager ロードすることで N + 1 問題を解決する

$ git diff
diff --git a/app/Http/Controllers/Admin/PostController.php b/app/Http/Controllers/Admin/PostController.php
index 4c080e9..0549a61 100644
--- a/app/Http/Controllers/Admin/PostController.php
+++ b/app/Http/Controllers/Admin/PostController.php
@@ -17,7 +17,7 @@ class PostController extends Controller
     public function index()
     {
         return view('admin.posts.index', [
-            'posts' => PostTypePost::postStatusAll()->orderByPostDateDesc()->get(),
+            'posts' => PostTypePost::with('user')->postStatusAll()->orderByPostDateDesc()->get(),
         ]);
     }

diff --git a/resources/views/admin/posts/index.blade.php b/resources/views/admin/posts/index.blade.php
index 3c0f12c..06159c9 100644
--- a/resources/views/admin/posts/index.blade.php
+++ b/resources/views/admin/posts/index.blade.php
@@ -27,7 +27,7 @@
         <tr>
           <th scope="row">{{ $post->ID }}</th>
           <td>{{ $post->post_title }} - {{ $post->post_status_description }}</td>
-          <td>{{ $post->user()->first()->display_name }}</td>
+          <td>{{ $post->user->display_name }}</td>
           <td>categories</td>
           <td>tags</td>
           <td>{{ $post->comment_count }}</td>
$

確認

https://localhost/admin/posts

おわりに

今回は、Laravel のリレーションと Eager ロードについてアウトプットしました。

カテゴリーとタグも同じように実装できれば楽だなあと思いつつ、データの構造に違いがあると思いますので、一筋縄では行かないと予想しております。

以上です。

コメントを残す