見出し画像

Laravel10(PHP8.2)+LaravelSail+MySQL8+phpMyAminで簡易的なECサイトを作るチュートリアル⑥

お疲れ様です。

いよいよこのLaravel10でのECサイト作成のチュートリアルも
ラストの記事となりました。

今までの記事はこちらです。

https://note.com/mukae9/m/me64989471c19

これまでの記事の中で
Laravelの基本的な動きが分かってきたのではないでしょうか。

ただし、Laravelにはまだまだ色々な仕組みがありますし
かなり有能なライブラリも多数あります。

Vue.jsと組み合わせてSPA(シングルページアプリケーション)を作るのも容易です。

Reactをフロントに置いてLaravelはAPIとして利用したり、
Flutterでモバイル開発をしつつそのAPIはLaravelとかもあります。
(最近だとある程度な規模感ならこんな感じで分け切ることが多いですね)

この記事が終わってからもLaravelのこと色々と勉強してみてくださいね。



1、課題の答え合わせ

全体的に前回の記事で詳しく説明している部分がほとんどの復習になりますので駆け足で進めていきます。
もしわからないところがあれば今までの記事で復習してみてくださいね。

課題①/deleteMyCartStockにPOSTでアクセスした場合にStockContorllerのdeleteMyCartStockメソッドを発動させる。

前回作成したカート画面で「カートから削除」のボタンを押すと発動するルートです。
ルーティングを記述するのはもちろん何回も出てきた

routes/web.php

です。

以下を追加します。

Route::post('/deleteMyCartStock', [StockController::class, 'deleteMyCartStock'])->name('stock.deleteMyCartStock');

Route::deleteもあるのですがblade側でも対応をしないと効果がないので今回は割愛。気になる方は調べてね。

課題②Eloquantを使ってカートテーブルから該当の商品かつログインユーザーのidと一致するレコードを削除する。

この課題はもちろん①で作ったdeleteMyCartStockメソッドの処理内容です。
StockController.phpにdeleteMyCartStockメソッドを作ります。

以下の処理を追記します。

   public function deleteMyCartStock(Request $request,UserStock $userStock)
   {

       //カートから削除の処理
       $stockId=$request->stockId;
       $message = $userStock->deleteMyCartStock($stockId);

       //追加後の情報を取得
       $myCartStocks = $userStock->showMyCart();

       return view('myCart',compact('myCartStocks' , 'message'));

   }

引数でリクエストとUserStockモデルを使えるようにしています。
//追加後の情報を取得
$myCartStocks = $userStock->showMyCart();
は他のメソッドでも使っている処理ですね。

こうやって関数化することで同じ処理を使い回しています。
使い回すという言い方だと手抜き感ありますが、

プログラミングの世界では反復する処理の関数化は基本的に正義です。

①仕様変更の際に関数化してる部分だけを修正すればOK
②コードが見やすくなる

特に①に関しては今回のケースでも、もしこのshowCart()内の処理に変更があった場合は、関数化していればそこだけの編集で全部に対応できますが、
もしaddCartやmyCartにそのままコピペして処理の中身を記述していた場合はもうすでに関数化している場合の3倍の修正が必要となるわけです。

今回のような簡易的なチュートリアルではまだいいですが、
これを実際の職場でしてしまうと

①修正に時間が何倍もかかって後輩に引かれる(そもそもどこで使ってたかも忘れてる)
②修正漏れが発覚して先輩に引かれる
③業務を引き継いだ新入社員や別会社の人に呪われる(これよくあるやつ)


っていう自体を起こしかねません。

リーダブルコードという名著にも書いてありますが、

一連の処理をコピペした瞬間に自分を疑ってください。

さて脱線しましたが
コントローラーの記述が終わったので
UserStockモデルに
deleteMyCartStockメソッドの処理を書いていきます。

Models/UsetStock.phpを開いてdeleteMyCartStockメソッドを追加します。

public function deleteMyCartStock($stockId)
{
       $userId = Auth::id(); 
       $deleteStockCount = $this->where('userId', $userId)->where('stockId',$stockId)->delete();
       
       if($deleteStockCount > 0){
           $message = 'カートから一つの商品を削除しました';
       }else{
           $message = '削除に失敗しました';
       }
       return $message;
}

$userId = Auth::id(); は何回も出てきているログインユーザーのid取得です。

$delete=$this->where('userId', $userId)->where('stockId',$stockId)->delete();

が今回のキモですが、
->where('userId', $userId)はよくあるSQLのwhere句です。
users_stocksテーブルのuserIdに$userIdと同じ値が入っていれば抽出してくれます。
さらにそこに連結させて、
->where('stockId',$stockId)をすることで
userIdが一致して、stockIdも一致するレコードを抽出します。
SQLのAND+whereと同じ働きですね。

もちろん
->orWhere()
というOR+whereと同じ働きをするのも準備されています。

そして
->delete();
で該当のレコードをバシュッと削除します。

削除を終えると
$deleteには
->delete()が影響を与えたレコードの数を返します。

つまり該当のレコードが一つ消えるはずなので、
「1」が格納されることになります。

なので条件分岐で
if($deleteStockCount > 0){
    $message = 'カートから一つの商品を削除しました';
}else{
    $message = '削除に失敗しました';
}
このようになってるわけですね。

あとは削除した場合としていない場合のメッセージをコントローラーに返してあげます。

return $message;

これであとはいつも通りカートページが表示されます。


試しにカート内の商品を全て削除してみましょう。
削除できましたね!!!

ただちょっと何も表示されないので味気ないですね、、、。

ここでbladeファイルはこういう時にとってもクールに条件分岐が可能です。
今回のケースだと、
ログインしているユーザーのカート情報が「あるかないか」で分岐ができそうですね。

■あった場合→今と同じ表示
■ない場合→「カートは空っぽです」

と表示させる。

で行きましょうか!

myCart.blade.phpを再編集します。

<x-app-layout>
    <div class="container-fluid">
        <div class="mx-auto" style="max-width:1200px">
            <h1 style="color:#555555; text-align:center; font-size:1.2em; padding:24px 0px; font-weight:bold;">
            {{ Auth::user()->name }}さんのカートの中身</h1>
                <p class="text-center">{{ $message ?? '' }}</p><br>
                <div class="">             
                    @foreach($myCartStocks as $stock)
                        <div class="text-center rounded shadow-lg bg-white p-6 m-4">
                        {{$stock->stock->name}} <br>                                
                        {{ number_format($stock->stock->fee)}}円 <br>
                            <div class="incart flex justify-center p-4 m-4">
                            <img src="/image/{{$stock->stock->imagePath}}" alt=""  width="600">
                            </div>
                            <form action="/deleteMyCartStock" method="post">
                                @csrf
                                <input type="hidden" name="stockId" value="{{ $stock->stock->id }}">
                                <input type="submit" value="カートから削除する">
                            </form>
                        </div>
                    @endforeach
                    {{-- 追加 --}}  
                    @if($myCartStocks->isEmpty())
                       <p class="text-center">カートはからっぽです。</p>
                    @endif
                </div>
            </div>
    </div>
</x-app-layout>

@if($myCartStocks->isEmpty())
//$myCartStocksが空だった時のための表示
@endif

これでカート内に商品がない場合の表示ができました。

2、最後に

ここまでお付き合いくださった皆様ありがとうございました。
まだまだLaravelのことで話せてないことの方が圧倒的に多いのですが、とりあえずLaravelの動きを知るためのチュートリアルとしての役割が果たせたのであれば幸いです。

このショッピングサイトですが
・Apiを使ったSNSログイン
・商品検索
・購入決済機能
・Admin側の商品追加機能

などなどまだまだ拡張できる要素があります。

あと間違ったURLでのリダイレクトとか、トランザクションとか購入ページのリロード問題とか、

そこらへんの記事もまた近々書くと思われますのでその時はぜひまたよろしくお願いします。(多分有料にする!数百円だけど!)

ただnoteに書くかわからんので
Twitterフォローしてくれたら喜びます。

https://twitter.com/Mukae9

あとめっちゃ書くのに時間かかったので今までの記事に全部いいねしていってください…笑

それではまた別の記事でお会いいたしましょう〜。
ありがとうございました!



この記事が気に入ったらサポートをしてみませんか?