前回の記事(Laravel + inertia + vue 環境でshadcn-vueを使う)で利用しているソースにリレーションに伴う修正と機能を追加しています。
Laravel でリレーションを設定し一般的なアプリケーションによくある機能を実装します。
ユーザーとブログ(1対多)
ユーザーとブログのリソースに対して1対多のリレーションを設定します。
ブログ一覧にリレーションで取得したユーザー情報を作者として表示します。
ユーザーの絞り込みを実装します。ユーザーを指定するコンポーネントとしてshadcn-vueからcomboboxを利用しました。
リレーションの設定
ブログのデータベース定義を変更しユーザーへの外部キーを設定します。
ユーザーとブログのモデル定義にリレーションを設定します。
ユーザーへの外部キーをブログに追加したので、ブログの新規登録と編集の機能を修正します。
ファクトリーを修正しサンプルデータを登録し直します。
ブログの編集画面で新規登録時のユーザー情報はinertiaのshared data機能を使って取得します。
実装した差分をgitHubにあげているので参考にしてください。
shadcn-vueのcombobox
shadcn-vue公式のドキュメントよりExamplesよりほぼコピペで使えました。
ちなみに、スターターキットをインストールした時点でバージョン等が利用を想定したものでない状態が起きているようで --legacy-peer-deps オプションを指定してインストールしたので、引き続きそのオプションを指定してインストールしています。スターターキット時点の問題はおそらくないだろうと想定しているというのもありますが動作させたいのが目的なので解決してないです。
Vueのcomputedとwatch
comboboxで選択したユーザーはリアクティブなのでwatchで変更を検知して一覧を更新します。
ページネーションのURLもユーザー情報を追加するためにcomputedを利用します。computedに引数を渡すには少し書き方に工夫がいるようです。下記のようにして引数を渡せるようにしました。
// resources/js/Pages/Posts/Index.vue
const nextPreviousLink = computed(() => (url) => {
if (!url) return undefined;
if (selectedUserValue) url += "&user_id=" + selectedUserValue.value;
return url;
});
ブログ一覧にユーザー情報(作者)を表示
Laravel公式のドキュメントよりリレーションされた情報を取得するために with メソッドを使います。LaravelのEagerロードという仕組みです。
// app/Http/Controllers/PostController.php
public function index(Request $request): Response
{
if ($request->user_id !== null){
$posts = Post::with('user')->where('user_id',$request->user_id)->latest()->paginate(10);
}else{
$posts = Post::with('user')->latest()->paginate(10);
}
return Inertia::render('Posts/Index', [
'posts' => $posts,
'users' => User::get(),
'selected_user_id' => $request->user_id,
]);
}
実装した差分をgitHubにあげているので参考にしてください。
ユーザーとブログ(多対多)
お気に入りのブログを登録する機能を実装するためにユーザーとブログに多対多のリレーションを設定します。
リレーションの設定
命名規則に従って中間テーブルの post_user を作成します。下記コマンドでマイグレーションファイルを作成します。
sail artisan make:migration create_post_user_table
ユーザーとブログのモデル定義にリレーションを設定します。
実装した差分をgitHubにあげているので参考にしてください。
お気に入りの設定機能
ブログの表示画面にお気入りかどうかの星のアイコンを表示し、クリックするたびにお気に入りのオン・オフが出来るように実装しました。
多対多のリレーションに対する中間テーブルの操作を attach() と detattch() メソッドを利用しています。
// app/Http/Controllers/FavoriteController.php
public function store($post_id)
{
Auth::user()->favorite_posts()->attach($post_id);
return back();
}
public function destroy($post_id)
{
Auth::user()->favorite_posts()->detach($post_id);
return back();
}
ブログの表示画面ではinertiaの useForm ヘルパー関数を利用してサーバーとの通信を実装しました。
// resources/js/Pages/Posts/Show.vue
<form
class="mb-4"
v-if="isFavourite"
@submit.prevent="
form.delete(route('favorite.destroy', post.id))
"
>
<Button variant="outline" size="lg">
<Star fill="yellow" strokeWidth="{1}" />
</Button>
</form>
<form
class="mb-4"
v-else
@submit.prevent="
form.post(route('favorite.store', post.id))
"
>
<Button variant="secondary" size="lg">
<Star fill="white" strokeWidth="{1}" />
</Button>
</form>
実装した差分をgitHubにあげているので参考にしてください。
ブログのコメント登録機能(1対多)
ブログに対してコメントを登録できる機能を実装します。
Laravel のネストしたリソースを扱うことを想定しています。
モデルとマイグレーション、リソースコントローラー、フォームリクエストの雛形を作成
下記コマンドでモデルとマイグレーション、リソースコントローラー、フォームリクエストの雛形を作成してくれます。
sail artisan make:model Comment -mcrR
リレーションの設定
ブログとコメント、ユーザーとコメントの各リソースに対して1対多のリレーションを設定します。
コメントのデータベース定義にブログとユーザーへの外部キーを設定します。
ユーザーとブログとコメントのモデル定義にリレーションを設定します。
実装した差分をgitHubにあげているので参考にしてください。
コメント表示と登録
ブログの表示画面に対して、コメントの登録と登録されたコメントの一覧を表示するように実装しています。コメントに関する部分をコンポーネントとして切り出して実装しました。
実装した差分をgitHubにあげているので参考にしてください。
タグの管理(1対多)
ユーザーが任意のタグを管理する機能を実装します。後述するブログにタグを設定する機能で利用します。
モデルとマイグレーション、リソースコントローラー、フォームリクエストの雛形を作成
下記コマンドでモデルとマイグレーション、リソースコントローラー、フォームリクエストの雛形を作成します。
sail artisan make:model Tag -mcrR
リレーションの設定
ユーザーとタグのリソースに対して1対多のリレーションを設定します。
実装した差分をgitHubにあげているので参考にしてください。
タグの管理画面
タグの一覧、新規登録、編集、削除の機能を1つの画面で実装しました。
実装した差分をgitHubにあげているので参考にしてください。
ブログにタグを複数設定(多対多)
タグの管理で作成したタグを任意のブログに複数設定出来るようにします。
リレーションの設定
Laravel の命名規則に従って中間テーブルの post_tag を作成します。
下記コマンドでマイグレーションファイルを作成します。
sail artisan make:migration create_post_tag_table
タグとブログのモデル定義にリレーションを設定します。
実装した差分をgitHubにあげているので参考にしてください。
shadcn-vueのcheckboxとbadge
checkbox は shadcn-vue公式のドキュメントよりほぼコピペで使えました。チェックした値を配列としたいので <CheckboxGroupRoot> を別途利用しました。ドキュメントに記載がありました。badge は迷うことなく使えました。
ブログへのタグ設定機能
任意のブログにタグ管理で作成したタグを設定します。
Laravel公式のドキュメントより多対多のリレーションに対する中間テーブルの操作を sync() メソッドを利用しています。
実装した差分をgitHubにあげているので参考にしてください。
タグでブログをフィルタリングする機能
ブログ一覧で、タグによるフィルタリングを実装します。
Laravel公式のドキュメントより多対多のリレーションに対する存在クエリを利用してタグによるフィルタリングを実装しました。
実装した差分をgitHubにあげているので参考にしてください。