Help us understand the problem. What is going on with this article?

LaravelでbelongsToManyしてみた。3 <タグから関連記事を取得>

  1. 中間テーブルの構成を作成
  2. 関連したタグを取得
  3. コレ
  4. まだあるかも。。

※前回までの物がない人は一読を推奨します。

タグの選択(ボタン要素を追加)

index.blade.php

<a href="twiite?tag={{ $tag }}" style="color: inherit">
    <p style="display: inline-block; margin-left: 10px; border: 1px solid 
    #5fa; max-width: 100px">
        {{ $tag }}
    </p>
</a>

タグの項目をaタグで囲んでみました。
今回はルートを通してないので、クエリでタグを持たせたいと思います。
ここでのリンクは例えば「https: //localhost:8080/twiite?tag=令和」などです。

クエリーデータを取得する場合以下があります。

$_GET['tag'];//html上
や
__construct(Request $request){
    $request->tag;
}//php上
などです。

ModelにbelongsToManyを追加

記事からやったのとまったく逆をやればいいのです。そう単純な話なのです。
ただ、attacheに関しては中間テーブルに記録する作業をタグからする意味も必要もないので、
そこは違うところです。あくまで今回は記事取得になります。
Tag.php に追加

public function twiites()
{
    return $this->belongsToMany(Twiite::class);
}

前と逆ですね。。これで、中間テーブルを使うことができます。

TwiiteController.php

public function index(Request $request)
    {
//省略...
+        if(!empty($request->tag)){//タグ情報がクエリで来ている場合。(検索)
+          $oneTagRecorde = $this->tag->where('name', $request->tag)
+            ->first();//タグを押してここに入るので、一意で一つしかないと予想される。
+          $twiiteList = $oneTagRecorde->twiites()
+            ->orderby('twiite_id')
+            ->get();//リレーションからタグに対応するツイートを全取得。
+        }
+        else{
          $twiiteList = $this->twiite->where('user_id',$userId)
            ->orderby('created_at','desc')
            ->get();//ツイート全件取得
+        }
//省略...  
        return view('index', compact('twiiteList', 'userId'));//index view
    }

処理を通常時の全レコード取得から、特定タグ情報が入ったものだけに変更します。
ここで、送ったクエリデータを判定し、何か入っていれば、タグ検索を
入っていなければ、通常の全レコード取得をするという流れになります。
その後の処理は前と待ったく同じです。。

投稿一覧 選択タグ色付けなど

選択して、関連記事が表示されるときに、
そのアクションを検知して、選択されているタグが赤くなるようにしてみますか。。
そして、どんな順番だろうと、選択タグが先頭に来るようにしましょう。

TwiiteController.phpのindex()

public function index(Request $request)
    {

       foreach($twiiteList as $twiiteRecord){
           $tags = $twiiteRecord->tags()->orderby('tag_id')->get();//中間テーブル経由でタグのrecordを取得
           $tagName = [];
+          $exchangeArray = 0;//先頭になるタグ名の番号
           foreach($tags as $tagRecord){//タグも複数あるので、繰り返す。
              $tagName[] = $tagRecord->name;//取得してきたレコードのid

+             if($request->tag === $tagRecord->name)//タグ名が選択タグと一致
+                $exchangeArray = count($tagName) - 1;//現在保存されているタグの場所n番目
           }

+          if($exchangeArray != 0){//先頭入れ替え
+            $name = $tagName[0];
+            $tagName[0] = $tagName[$exchangeArray];
+            $tagName[$exchangeArray] = $name;
+          }

           $twiiteRecord['tags'] = $tagName;//送るデータに追加(同foreachで回すため)
         }
         return view('index', compact('twiiteList', 'userId'));//index view
    }

検索タグがあれば、その番号を保存しておいて、先頭と入れ替える
という処理を追加。
そのほかデータの取得などは前々回と同じことなので、コメントアウトと、前のを見てください。
index.blade.php

<?php $first = true; ?>
@foreach($twiite->tags as $tag)
<a href="twiite?tag={{ $tag }} " style="
      <?php echo !empty($_GET['tag']) & $first ?
       'color: red' : 'color: inherit'?>
">
   <?php $first = false; ?>
   <p style="display: inline-block; margin-left: 10px; border: 1px solid #5fa; max-width: 200px">
      {{ $tag }}
   </p>
</a>
@endforeach

先頭に検索タグを持ってきたので、foreachのループ一回目だけ行いたいので、
$first = true;とかしています。
方法は好きなやり方で、やってください。
今回は三項演算子を使って、ifをしています。
ここでの条件は、クエリにタグ情報があるか? かつ 一回目か(初期のtrueか)?
これで、なければそのまま黒字に、あれば、先頭だけ赤文字になります。

完成

一通りやりたい機能は達成できました。
- 記事にタグを追加して保存、そのリレーション。
- 中間テーブルから関連タグを取得してきて、表示。
- タグからの記事検索。
- 検索結果の表示結果整形。

基本はもう動きますね。ただ、コードが汚いのと、長いので、まだ改良はできますが、
まあ、良しとしましょう。。w
今回一連の記事の流れは以上、記事とタグの中間テーブルが使いてぇという内容です。完結!

こちらに動かした動画がありますので、どうぞ参考に。
※音無しです。
今回のコード
gitに挙げてますので、どんどん使ってください。issueしていただいても結構ですよー。
本場で働いているので、まあ、答えられる範囲で答えます。では。。

次回は

あるかも。。一通り削除とかも付けてみようか?なんて思ってます。
ちょっと動かしておくのも面白いかと。。。
やるかわからないですw

ーー追記ーー
本記事シリーズの完成版はこちら。gitの管理をしっかりしました。
https://github.com/175B005/vueLaravel

また違うのをやっていくので、ここのブランチはvue.jsで追加していく用です。
belongstomanyというブランチでここまでを残しておきますので、
どうぞよろしくお願いします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした