学んだこと
- 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 ロードについてアウトプットしました。
カテゴリーとタグも同じように実装できれば楽だなあと思いつつ、データの構造に違いがあると思いますので、一筋縄では行かないと予想しております。
以上です。