laravel vue.jsでお気に入り機能を作る

#使用するファイル
・User.php
・ProductController.php
・index.blade.php
・LikeComponent.vue
・app.js
・LikeController.php



#Userモデルにて多対多のリレーションを行う。
```User.php
  public function likeProducts()
    {
        return $this->belongsToMany(Product::class, 'like_products');
    }
```
多対多のリレーションを行う。
belongsToManyの第一引数にリレーション先モデル名、第二引数に中間テーブル名を指定している。

#ProductControllerからindex.blade.phpに商品データを送る
```ProductController.php
 public function index(ProductSearchService $productSearchService, Request $request)
    {
        $likeProducts = Auth::user()->likeProducts()->pluck('product_id');
        $products = $productSearchService($request);
        return view('products.index', compact([
            'products',
            'likeProducts',
        ]));
    }

```
`Auth::user()->likeProducts()->pluck('product_id');`
先ほど多対多のリレーションを行なったのでそれを使用する。
中間テーブルであるlike_productsにログインユーザーが登録したproduct_idをコレクションで取得している。


#viewを用意（ここにlike-component)を埋め込む
```index.blade.php
<div class="row pt-2 px-5">
    @foreach ($products as $product)
    <a href="{{ route('products.show', $product->id) }}" class="mb-5 ml-5">
        <img src="{{ asset('storage/product_images/'.$product->image_path_one) }}" style="width: 100px; height: 100px;"
            class="img-thumbnail mx-auto d-block">
        <div class="center-block">
            <p class="text-center">{{ $product->name }}</p>
            <p class="text-center">¥{{ number_format($product->price) }}</p>
        </div>
    </a>

    <div id="app">
        <like-component :product-id="{{ $product->id }}" :liked-data="{{ $likeProducts  }}"></like-component>
    </div>
    @endforeach
</div>
```
foreachでコントローラーから送られてきた商品データのコレクションを一つずつ展開している。
like-componentへv-bindで展開したproductIdとログインユーザーがlike_productsテーブルに格納しているproductIdを渡している。
v-bindでの変数はケバブケースでないといけない。

```LikeComponent.vue
<template>
  <div>
    <i
      v-on:click="storeOrDelete"
      :class="[isActiveTrue === true ? 'far fa-heart ml-3' : 'fas fa-heart ml-3']"
    ></i>
  </div>
</template>

<script>
export default {
  props: ["productId", "likedData"],
  data() {
    return {
      isActiveTrue: this.likedData.includes(this.productId) ? false : true
    };
  },
  methods: {
    change() {
      this.isActiveTrue = !this.isActiveTrue;
    },
    storeProductId() {
      axios
        .post("like/" + this.productId, {
          productId: this.productId
        })
        .then(response => {
          console.log("success");
        })
        .catch(err => {
          console.log("error");
        });
    },
    deleteProductId() {
      axios
        .delete("like/" + this.productId, {
          data: {
            productId: this.productId
          }
        })
        .then(response => {
          console.log("success");
        })
        .catch(err => {
          console.log("error");
        });
    },
    storeOrDelete() {
      const isTrue = this.likedData.includes(this.productId);
      if (isTrue === true) {
        this.deleteProductId();
        this.change();
      } else {
        this.storeProductId();
        this.change();
      }
    }
  }
};
</script>
```
propsで先ほどindex.blade.phpから渡されたproduct-idとliked-dataを受け取っている。
先ほど渡す時はケバブケースだったが、こちらではローワーキャメルケースで書かないといけない。

storeOrDeleteメソッドの説明をする。
`const isTrue = this.likedData.includes(this.productId);`
likeData（ユーザーがお気にいりしているproductIdが配列で格納されている）の中にその商品のIDがあるかincludesメソッドで調べている。もし、ある商品（お気にりしているということ）ならお気に入りから外し、なければお気に入り登録する。
changeメソッドでstyleの切り替えを行なっている。

`:class="[isActiveTrue === true ? 'far fa-heart ml-3' : 'fas fa-heart ml-3']"`
はisActiveTrueがtrueかfalseでスタイルの切り替えをおこなっている。

#作成したコンポーネントを使用できるようにする
```app.js
Vue.component('like-component', require('./components/LikeComponent.vue').default);

new Vue({
    el: '#app',
});
```
`Vue.component('like-component', require('./components/LikeComponent.vue').default);
`
で先ほど作成したlike-componentを読み込んでいる。

`new Vue({
    el: '#app',
});`
でindex.blade.phpの#app内でvue.jsが使えるようになる。


#like-componentから非同期で送られてきたproductIdをlike_productsテーブルに登録・削除を行う。
```LikeProductController.php
  public function store(Product $product)
    {
        Auth::user()->likeProducts()->attach($product);
    }

    
    public function delete(Product $product)
    {
        Auth::user()->likeProducts()->detach($product);
    }
}
```

storeメソッドでは、like_productsテーブルにログインしているユーザーのIDとメソッドインジェクションの$product（like-componentから非同期で送られてきたproductId）をインサートしている。deletメソッドでは、反対に削除している。

これでお気に入り機能が完成した。