プロフィールの更新履歴を保存する仕組みを作るにはどのようにしたら良いのか。手順をまとめてみた。（自分用）



#はじめに
※ Profile画面を作っていますので、profile（自分用）として色々記載しています。

実際のアプリケーション開発はある機能が1つのテーブルを使うだけで完結することは、ほとんどありません。

複数のテーブルを使ってシステムを実現します。
リレーショナルデータベースにはこのようなテーブル同士の関連を扱う機能が備わっており、
Eloquentで扱うことができます。
編集履歴は「Profileをいつ変更したか」「日付と時刻を記録し、参照することができる」機能のことです。

編集画面でデータを更新するタイミングで histories というテーブルにデータを登録し、
編集画面でその一覧を見られるように実装します。

では、流れに沿って記述していきます。

#1.編集履歴テーブルの作成と関連付け
Migrationファイルの雛形を作成します。

```
$ php artisan make:migration create_histories_table
```

Migrationファイルを次のように編集いたします。

```php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateHistoriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('histories', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('profile_id');
            $table->string('edited_at');

            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('histories');
    }
}
?>
```

Migrationを実行します。

```
$ php artisan migrate
```

Modelの雛形を作成します。

```
$ php artisan make:model History
```
app/History.php で History Modelを下記のように実装します。

```php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class History extends Model
{
    protected $guarded = array('id');

    public static $rules = array(
        'profile_id' => 'required',
        'edited_at' => 'required',
    );
}
?>
```
Profile Modelとの関連を定義するために、app/Profile.php へ以下の内容を追記します。

```php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Profile extends Model
{
    protected $guarded = array('id');

    public static $rules = array(
        'name' => 'required',
        'gender' => 'required',
        'hobby' => 'required',
        'introduction' => 'required',
    );

    // Profileモデルに関連付けを行う
    public function histories()
    {
    return $this->hasMany('App\History');
    }
}
?>
```
Profileモデルに関連付けを定義することで、

Profileモデルから $profile->histories() のような記述で簡単にアクセスすることができます。


#2.編集履歴の記録と参照
ProfileController の update Actionで、Profile Model を保存するタイミングで、
同時にHistory Model にも編集履歴を追加するように実装します。

update Action を次のように変更。

```php

<?php
public function update (Request $request)
{
    // validationをかける
    $this->validate($request, Profile::$rules);
    // Profile Model から データを取得する
    $profile = Profile::find($request->id);
    // 送信されてきたフォームデータを格納する
    $profile_form = $request->all();
    unset($profile_form['_token']);
    // 該当するデータを上書きして保存する
    $profile->fill($profile_form)->save();

    retern redirect('admin/profile');
}
?>
```

#3.Viewを実装する
resources/views/admin/profile/edit.blade.php に以下を記述します。

```php

{{-- layouts/profile.blade.phpを読み込む --}}
@extends('layouts.profile')


{{-- profile.blade.phpの@yield('title')にProfileの編集'を埋め込む --}}
@section('title', 'Profileの編集')

{{-- profile.blade.phpの@yield('content')に以下のタグを埋め込む --}}
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 mx-auto">
            <h2>MyProfile編集画面</h2>
            <form action="{{ action('Admin\ProfileController@update') }}" method="post" enctype="multipart/form-data">
                @if (count($errors) > 0)
                <!-- errors内に個数があるならば配列中の個数を返す -->
                <ul>
                    @foreach($errors->all() as $e)
                    <!-- $errors内をループし、その中身を$eで表示する -->
                    <li>{{ $e }}</li>
                    @endforeach
                </ul>
                @endif
                <div class="form-group row">
                    <label class="col-md-2">氏名</label>
                    <div class="col-md-10">
                        <textarea class="form-control" name="name" rows="1">{{ old('body') }}</textarea>
                    </div>
                </div>
                <div class="form-group row">
                    <label class="col-md-2">性別</label>
                    <div class="col-md-10">
                        <input type="radio" name="gender" value="male">男性
                        <input type="radio" name="gender" value="male">女性
                    </div>
                </div>
                <div class="form-group row">
                    <label class="col-md-2">趣味</label>
                    <div class="col-md-10">
                        <textarea class="form-control" name="hobby" rows="10">{{ old('body') }}</textarea>
                    </div>
                </div>
                <div class="form-group row">
                    <label class="col-md-2">自己紹介欄</label>
                    <div class="col-md-10">
                        <textarea class="form-control" name="introduction" rows="12">{{ old('body') }}</textarea>
                    </div>
                </div>
                <input type="hidden" name="id" value="{{ $profile_form->id }}">
                {{ csrf_field() }}
                <input type="submit" class="btn btn-primary" value="更新">
            </form>
        </div>
    </div>
</div>
@endsection
```

次に Routing　を実装する
routes/web.php に追加するRouting設定です。

```php
<?php
Route::get('profile/edit', 'Admin\ProfileController@edit');
Route::post('profile/edit', 'Admin\ProfileController@update');
?>
```
編集画面に実際にブラウザでアクセスしてみましょう。
一覧画面にある表の1番右側に、編集リンクがあります。
このリンクから編集画面に遷移し、実際にデータが編集できるか試してみましょう。


#4.データの削除
データの削除は、データの更新と同じくモデルを取り出してから削除を指示します。

#5.Controller を実装する
ProfileController に delete Action を追加してください。

```php

<?php

public function delete(Request $requsest)
{
    // 該当する Profile Modelを取得
    $profile = Profile::find($request->id);
    // 削除する
    $profile->delete();
    return redirect('admin/profile');
}

?>
```

次はデータの削除について考えていきます。
一般的に削除に対応するアクション名はdeleteになります。

データをセーブするときは、$profile->save(); で save メソッドを利用しましたが、
データの場合はdelete()メソッドを使います。

#6.Routing を実装する
routes/web.php に追加する Routing 設定です。

```php

Route::get('profile/delete', 'Admin\ProfileController@delete');
```

削除機能は画面を持たず、id で指定されたモデルをすぐに削除します。
コントローラの最後の画面で一覧画面にリダイレクトしているため、
削除機能を持っていません。

そのため、ビューテンプレートは不要となる。
今回は以上です！
完全自分用のノートになってしましたすいません。
それでは
明日は今日以上のパフォーマンスを٩( ᐛ )و