💨

laravel タグ付け機能の実装

2020/10/23に公開1

完成形


↑このようにフォームで記入し


↑取得したタグを表示

①多対多のリレーション

https://engineering.mobalab.net/2019/06/21/laravelの多対多のリレーションについて/
こちらのサイトを参考にさせていただきました。

tagテーブル、tagテーブルを紐付けたいデータベース(今回はoutfit)、中間テーブルとであるoutfit_clothテーブルをそれぞれ作成。

各モデルでリレーションを定義

Tag
public function outfits()
{
	return $this->belongToMany(App\Outfit);
}
Outfit
public function tags()
{
	return $this->belongToMany(App\Tag);
}

②コントローラーの処理

正規表現を使って#以降のみを取得

preg_match_all('/#([a-zA-Z0-90-9ぁ-んァ-ヶー一-龠]+)/u', $request->tag_name, $match);

preg_match_all — 繰り返し正規表現検索を行う(PHPリファレンスより)
第一引数→条件
():グループ化
a-z:小文字アルファベット
A−Z:大文字アルファベット
0-9:半角数字
0−9:全角数字
ぁ-んァ-ヶー一-龠:ひらがなカタカナ漢字
[]:この中の任意の一文字に該当する
+:直前の表現を1回以上繰り返す
u:マルチバイト(UTF-8)対応 PHPのみ

第二引数→検索される文字列
$requestをコントローラーの引数にして、フォーム(name="tag_name")からのpostデータを取得

第三引数→条件にマッチした引数が配列の形でわたされる

dd($match)

で確認すると、

となっている。

foreach($match[1] as $input)
{
	//すでにデータがあれば取得し、なければデータを作成する
	$tag=Tag::firstOrCreate(['name'=>$input])
	//$tagを初期化($tagに配列でデータが入ってしまうため)
	$tag=null;
	//入力されたタグのidを取得
        $tag_id=Tag::where('name',$input)->get(['id']);
        //タグとoutfitの紐付け
        $outfit=Outfit::find($outfit_id);
        $outfit->tags()->attach($tag_id);
}

firstOrCreate()
()内の条件でマッチするものがあればfirst()で取得、なければcreate()

Bladeの書き方

<div>
	@foreach($outfit->tags as $outfit_tag)
		<span class="badge badge-pill badge-info">{{$outfit_tag->name}}</span>
        @endforeach
</div>

bootstrapであれば、badgeクラスでタグっぽく作成可能

Discussion