ポートフォリオ作成時メモ　part12 ~PostモデルとMapInfoモデルのリレーション問題②~

## はじめに
こんにちは、未経験からエンジニア転職を目指しているものです。
オンラインスクールで本格的に学習して7ヶ月目に入りました。
PHP,Laravelを学習しポートフォリオを作成中です。
Postモデルに紐づいているMapInfoモデルとのリレーションに悪戦苦闘したため、解決までの内容を整理しました。

## 概要
Laravel Sailを使った開発環境で、Google Maps APIを利用して地図を描画しました。
新規投稿作成画面に地図情報が反映されるようになりましたが、PostモデルとMapInfoモデルが紐づいた事で、新たな問題が発生しました。

**1. 　投稿した内容が、投稿一覧に反映されず、エラーが発生**
**2. 　1.の解決後、投稿編集画面を作成したが、updateが機能しない**

今回は2について解説していきます。
1については、下記を参照頂けると幸いです。

https://qiita.com/pila-suzuki/items/0ed118a814ee09e69a6a

## 投稿編集画面を作成したが、updateが機能しない
ディレクトリ構成としては下記になります
- show.blade.php：   投稿詳細画面
- edit.blade.php：   投稿編集画面

処理の流れは下記になります。
- show.blade.phpで編集ボタンをクリック　
- PostControllerのeditメソッドが機能　
- edit.blade.phpへ遷移　
- データを更新し、保存ボタンをクリック
- PostControllerのupdateメソッドが機能　
- show.blade.phpへ遷移し正しく表示される

## 原因の特定に向けた検証 part1
データベース上を確認し、データが更新されていない事を確認
→updateメソッドが機能していないのでは？


## 原因の特定に向けた検証 part2
PostControllerのupdateメソッドの内容を確認（下記参照）
- リレーションに関する記述は問題なさそう

```php
public function update(Request $request, $id)
    {
        $post = Post::with('mapInfo')->findOrFail($id);

        // 自分の投稿以外は403エラー
        if ($post->user_id !== auth()->id()) {
            abort(403, 'Unauthorized action.');
        }

        $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required|string',
            'location_name' => 'required|string|max:255',
            'latitude' => 'required|numeric',
            'longitude' => 'required|numeric',
            'preferred_gender' => 'nullable|string',
            'preferred_group_size' => 'nullable|string',
        ]);

        // 投稿データを更新
        $post->update([
            'title' => $request->input('title'),
            'content' => $request->input('content'),
            'location_name' => $request->input('location_name'),
            'preferred_gender' => $request->input('preferred_gender'),
            'preferred_group_size' => $request->input('preferred_group_size'),
        ]);

        // 関連する地図情報を更新
        $mapInfo = $post->mapInfo;
        if ($mapInfo) {
            $mapInfo->update([
                'activity_location' => $request->input('location_name'),
                'latitude' => $request->input('latitude'),
                'longitude' => $request->input('longitude'),
            ]);
        } else {
            // MapInfoが存在しない場合、新規作成
            MapInfo::create([
                'post_id' => $post->id,
                'activity_location' => $request->input('location_name'),
                'latitude' => $request->input('latitude'),
                'longitude' => $request->input('longitude'),
            ]);
        }

        Log::info('MapInfo updated successfully or created', ['post_id' => $post->id]);

        return redirect()->route('posts.show', $post->id)->with('status', '投稿を更新しました。');
    }


```

### laravel.logでクエリが正しく動作している事を確認
データベース上の更新がされていない事の確認方法
- データベースのログ確認
データベース操作が実行されているか、Laravelが実際にSQLクエリを発行しているかを確認
- 手順
 `config/database.php` の DB_CONNECTION を確認。
デバッグ用に SQLログ を出力するため、app/Providers/AppServiceProvider.php に次の内容を追加
```php
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

public function boot()
{
    if (config('app.debug')) {
        DB::listen(function ($query) {
            Log::info($query->sql, $query->bindings);
        });
    }
}
```

この設定により、データベースクエリ が storage/logs/laravel.log に出力される。
update 実行時にクエリが出力される事を確認。
→edit.blade.phpに問題があるのでは？

## 原因の特定に向けた検証 psrt3
edit.blade.phpで地図情報に関係する場所を確認
経度と緯度の値を入力するinput部分が抜けていることに気づく


地図表示部分を修正した所、解決。（下記参照）
```PHP
<!-- 地図 -->
<div id="map" class="w-full h-64 rounded-md shadow-md"
    data-latitude="{{ $post->mapInfo->latitude ?? '35.6895' }}"
    data-longitude="{{ $post->mapInfo->longitude ?? '139.6917' }}"
    data-location-name="{{ $post->mapInfo->activity_location ?? '不明な場所' }}">
</div>

 // この部分の記載がなかった。
<input type="hidden" id="latitude" name="latitude" value="{{ $post->mapInfo->latitude ?? '' }}">
<input type="hidden" id="longitude" name="longitude" value="{{ $post->mapInfo->longitude ?? '' }}">
```

## まとめ
前回までのエラーの傾向から当初はPostControllerやモデルに原因があると思いこんでいた。
原因を洗い出していくなかで、画面の表示部分であるviewに問題があると発見。
改めて、どの動きの過程で問題が起きているかを一つずつ確認していくことが大切であると実感した。


最後まで、ご視聴頂きありがとうございます。