💨
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
この記事もだし、参考元の記事も有能すぎる🙏