Laravel

Laravelで「いいね」機能を実装する方法

いつもご利用ありがとうございます。このブログは、広告費によって運営されています。

オススメ本
Web技術を勉強するなら、かなりオススメの雑誌です。毎月新しい発見があります。ついに最終号・・・、みなさん買いましょう!!
読んで損することはない名著。命名で悩むことが多い人はこの本がオススメです。

⇨ Laravel 記事の目次はこちら

Laravel で、「いいね」機能を実装する方法について、まとめてみました。

前提条件

  1. post の詳細ページでの実装
  2. ユーザーが、post に対していいねをする
  3. Ajax で非同期通信する
Laravel Framework 8.83.8

テーブル設計

このように users と posts と likes テーブルがあります。

likes table

likes テーブルは、多対多の中間テーブルとなります。

Laravel で多対多のリレーションをして保存、表示する方法【belongsToMany】

マイグレーションファイル

likes テーブルを作成します。その他のテーブルの作成については省略します。

コマンドでファイルを生成します。

php artisan make:migration create_likes_table

databases/migrations/今生成したマイグレーション ファイルを編集する

Schema::create('likes', function (Bluepr$table) {
    $table->id();
    $table->bigInteger('post_id');
    $table->bigInteger('user_id');
    $table->timestamps();
});

User モデルと、Like モデルにリレーションを書く

最初に、Like モデルを作成します。

コマンドを打ちます。

php artisan make:model Like

User モデルにリレーションを書く

ここに書いている内容は

    //多対多のリレーションを書く
    public function likes()
    {
        return $this->belongsToMany('App\Models\Post','likes','user_id','post_id')->withTimestamps();
    }

    //この投稿に対して既にlikeしたかどうかを判別する
    public function isLike($postId)
    {
      return $this->likes()->where('post_id',$postId)->exists();
    }

    //isLikeを使って、既にlikeしたか確認したあと、いいねする(重複させない)
    public function like($postId)
    {
      if($this->isLike($postId)){
        //もし既に「いいね」していたら何もしない
      } else {
        $this->likes()->attach($postId);
      }
    }

    //isLikeを使って、既にlikeしたか確認して、もししていたら解除する
    public function unlike($postId)
    {
      if($this->isLike($postId)){
        //もし既に「いいね」していたら消す
        $this->likes()->detach($postId);
      } else {
      }
    }

web.php にルーティングを追加する

web.php に以下の2行を追加

Route::post('/like/{postId}',[LikeController::class,'store']);
Route::post('/unlike/{postId}',[LikeController::class,'destroy']);

コントローラーに追加・削除の関数を追加する

コマンドで LikeController を作成します

php artisan make:controller LikeController

LikeController を編集する

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use Auth;

class LikeController extends Controller
{
    public function store($postId)
    {
        Auth::user()->like($postId);
        return 'ok!'; //レスポンス内容
    }

    public function destroy($postId)
    {
        Auth::user()->unlike($postId);
        return 'ok!'; //レスポンス内容
    }
}

いいねボタンを作成する

投稿詳細ページを表示するファイルや、ルーティングなどは割愛して、実際に「いいね」するためのボタンを作るところだけ書きます。

***.blade.php に「いいね」ボタンを作成する

<button onclick="like({{$post->id}})">いいね</button>

とりあえず、これでよいでしょう。

このボタンを押した時、onclick で指定している like という関数が動きます

onclick で動かす、like 関数を作る

js ファイルを作成して以下のような関数を作成します。

function like(postId) {
  $.ajax({
    headers: {
      "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
    },
    url: `/like/${postId}`,
    type: "POST",
  })
    .done(function (data, status, xhr) {
      console.log(data);
    })
    .fail(function (xhr, status, error) {
      console.log();
    });
}

実際に押してみる!

データベースの likes テーブルにデータが追加されたら OK です!

うまくいかない場合のデバッグ方法

Laravel でデバッグする方法

【初心者向け】Laravel で 419 エラーが発生して POST できないとき

Laravel で app.js や app.css が 404NOT FOUND するときの解決方法

チェック項目 ① コンソールを確認する

コンソールというのは、グーグル Chrome などでついている機能で、

右クリック ⇨ 検証 ⇨ コンソールで見られます。

Mac だとショートカットキーで

(Command + Option + I) ⇨ コンソール

で見られます。

ここで500エラーなのか、404エラーなのかなどが分かります。

500 エラーの場合、以下の記事を読んでデバッグしてみてください。

Laravel でデバッグする方法

チェック項目 ② JavaScript は動いているか?

最後に作成した関数を以下のようにして、関数が動いているか(検証 ⇨ コンソールで文字が出力するか確認してみてください)

function like(postId) {
  console.log("動いてる?");
}

最後に、いいね解除の表示を作る

<button onclick="unlike({{$post->id}})">いいね解除</button>
function unlike(postId) {
  $.ajax({
    headers: {
      "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
    },
    url: `/unlike/${postId}`,
    type: "POST",
  })
    .done(function (data, status, xhr) {
      console.log(data);
    })
    .fail(function (xhr, status, error) {
      console.log();
    });
}

Vue の場合

Laravel でのコードは、そのままで大丈夫です。

vue ファイルを変更します

<button @click="like(post.id)">いいね</button>
<script>
  export default {
    data() {
      return {
        post: {}, //postの情報がこの変数に入っている前提です。
      };
    },
    methods: {
      like(postId) {
        axios.post(`/like/${postId}`).then(({ data }) => {
          console.log(data);
        });
      },
    },
  };
</script>

post の一覧画面で「いいね」をする

jQuery で実装する

さきほど書いた JS の関数で実装できます。

@foreach($posts as $post)
<div>
  <div>{{ $post->title }}</div>
  <button onclick="like({{ $post->id }})">いいね</button>
</div>
@endforeach

Vue で実装する

<template>
  <div>
    <div v-for="post in posts">
      <div>{{ post.title }}</div>
      <button @click="like(post.id)">いいね</button>
    </div>
  </div>
</template>

まとめ

以上です。いいね機能を実装してみました。

誰かの参考になればと思います。

感想・苦情、追加して欲しい記事がありましたら お問い合わせフォーム にご連絡ください。

それでは!

人気記事

PHP7.4 + Laravel6 のプロジェクトを AWS EC2 にデプロイする

【laravel-breadcrumbs】Laravel でパンくずリストを実装する