Laravel：フラッシュメッセージを表示する



# 概要
記事が追加された時に上の方にメッセージを表示するようにします。
セッションを使って、リダイレクト先で一回だけ表示できます。

##▶ 動作確認環境
- php 7
- Laravel 5.7



# やり方



##▶ Controller を編集

セッションにフラッシュメッセージを渡します。

書き方は色々あります

```php:Controllerのstoreメソッド
    return redirect('/')->with('flash_message', '投稿が完了しました');
```

とか

```php:Controllerのstoreメソッド
    session()->flash('flash_message', '投稿が完了しました');
    return redirect('/');
```

```php:Controllerのstoreメソッド
    \Session::flash('flash_message', '投稿が完了しました');
    return redirect('/');
```

こんな感じで。



##▶ Viewを編集する

###- Viewにメッセージ表示領域を追加する

Viewの中にフラッシュメッセージを表示する場所を作ります。
どこでもいいですが私は親テンプレートに追加します。

フラッシュメッセージがある時だけ表示させたいので`@if`で括ります。

```php:resources/views/layouts/myapp.blade.php
        <!-- フラッシュメッセージ -->
        @if (session('flash_message'))
            <div class="flash_message">
                {{ session('flash_message') }}
            </div>
        @endif

        <main class="mt-4">
            @yield('content')
        </main>
```

基本これでOKです。


# スタイルをあてる

おしゃれにしたいから

##▶ レシピ1:BootstrapとJavaScript
###- CSS

Bootstrapでsuccessな感じにする

```html:viewのどこか

<!-- フラッシュメッセージ -->
        @if (session('flash_message'))
            <div class="flash_message bg-success text-center py-3 my-0">
                {{ session('flash_message') }}
            </div>
        @endif
```

###- JavaScript

ちょっと時間おいたらふーっと消えてもらう。
ただし消える時はdiv要素ごとなので、
消えた途端にフラッシュメッセージの下のコンテンツがごそっと上に動く

```javascript:public/js/main.js

(function() {
	'use strict';

	// フラッシュメッセージのfadeout
	$(function(){
		$('.flash_message').fadeOut(3000);
	});

})();

```


##▶ レシピ2 toastrを使う

###- 必要なスクリプトを埋め込む

この3つをviewに埋め込む

```html
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
```




###- フラッシュメッセージの表示部を埋め込む

とりあえずsuccessのみ用意。

```html

        <!-- フラッシュメッセージ -->
        <script>
            @if (session('flash_message'))
                $(function () {
                		toastr.success('{{ session('flash_message') }}');
                });
            @endif
        </script>

```

###- 動作確認

![flash_msg.png](https://qiita-image-store.s3.amazonaws.com/0/275623/61741cb9-13dc-7283-d895-6ab06d6c3a6d.png)

良さそうです。



###- 成功、失敗のそれぞれ用意する

成功のグリーンのメッセージと
失敗時の赤いメッセージとそれぞれ作る



```html
<script type="text/javascript">
			// {{--成功時--}}
			@if (session('msg_success'))
				$(function () {
					toastr.success('{{ session('msg_success') }}');
				});
			@endif

			// {{--失敗時--}}
			@if (session('msg_danger'))
				$(function () {
					toastr.danger('{{ session('msg_danger') }}');
				});
			@endif
</script>

```

Controllerの名前も変える。
よきところにmsg_dangerも置く。

```php:Controllerのstoreメソッド
    // ”msg_success”に名前を変える
    session()->flash('msg_success', '投稿が完了しました');
    return redirect('/');
```




# ログイン、ログアウトにも利用する

記事の投稿・更新だけではなく、ログイン、ログアウトした時にも表示するようにします。


##▼ ログイン

セッションにフラッシュメッセージをセットするだけでOKです。

```php:app/Http/Controllers/Auth/LoginController.php

    /**
     * ログインした時のリダイレクト先
     * Where to redirect users after login.
     *
     * @var string
     */
    // protected $redirectTo = '/home';
    protected function redirectTo() {
        session()->flash('msg_success', 'ログインしました');
        return '/home';
    }
```


##▼ ログアウト

ログアウトに関しては[Illuminate\Foundation\Auth\AuthenticatesUsers](https://github.com/laravel/framework/blob/5.7/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php)トレイトでlogtou()が定義されているので、これをオーバーライドします。

（テスト中）

# 参考

:link: readouble.com [フラッシュデータを保存するリダイレクト](https://readouble.com/laravel/5.7/ja/responses.html#redirecting-with-flashed-session-data)
:link: readouble.com [フラッシュデータ](https://readouble.com/laravel/5.7/ja/session.html#flash-data)
:link: Github [[Laravel] Session(Flash)の使い方](https://gist.github.com/graffiti-withwind/1cc69776106b6c081d879b36666179aa)