#6 Controllerの作成 ~laravel×AWSで掲示板を作ろう~

#laravel×AWSで掲示板を作ろう
本記事は、laravel×AWSの第6回です。
作ったサイト：<https://vible.jp>

【参照】
1. [完成形イメージ](https://qiita.com/surasurag/items/2ebce801a9ed04804e08>)
2. AWSサーバを立てる（工事中）
3. サーバにlaravelを導入してRDSと連携する（工事中）
4. [データベース構築](https://qiita.com/surasurag/items/f9be44372c41f83cc543)
5. [Modelの作成](https://qiita.com/surasurag/items/5db521b4877f829ffca7)
6. [Controllerの作成](https://qiita.com/surasurag/items/6e69247cdbb077fac31a)
7. [いいね機能の実装](https://qiita.com/surasurag/items/0141d48d2869bd1bd913)
8. [ルーティングの実装](https://qiita.com/surasurag/items/2f00d36fdeadf52438bf)

#Controllerとは？
view(HTML表示画面)とデータベースとの連携を担当している、という理解です。データベースから値を引っ張ってくる際、様々な条件（特定のIDのみ、特定の日時のみ）を指定してあげる必要があります。HTML画面で直接記述すると、とんでもない記述量となってしまうため、そういう作業を裏で別の場所でやろうということです。

#Controller作成手順
本サービスは「悩み投稿機能」「ツイート投稿機能」の２本立てでできているため、Controllerを２つに分けました。

QuestionController：悩み投稿関連の処理を担当
TweetController：ツイート投稿関連の処理を担当

ここではQuestionControllerの作成手順を説明します。

まずは以下のコマンドで。

```
$ php artisan make:controller Question
```

これでapp\Http\Controllers直下にファイルが作成されました。
![controller.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832092/567ca1ef-7bae-74f1-4363-c24bd42a2112.png)


質問投稿に関する機能として、以下８つの機能を実装します。

| 実装機能      　  |     function名  | 
|:-----------------|---------------- |
| 質問内容一覧といいね数を渡す        |  index      |
| 各質問に対するいいねの追加と削除           |    ajaxlike       |
| 質問投稿   |nayami_add |  
| 新たな質問を登録   |nayami_create | 
| 各質問内容の詳細とそれに対するアドバイス一覧を渡す     |   detail | 
| 各質問に対するアドバイスの登録   |nayami_answer |  
| 各アドバイスに対するいいねの追加と削除     |   answer_question_like | 
| 投稿した質問の削除   |nayami_destroy |   


Cotrollerを以下のように編集してください。


```php:QuestionController.php
<?php

namespace App\Http\Controllers;

use App\Question;
use App\QuestionLike;
use App\User;
use App\AnswerQuestion;
use App\AnswerQuestionLike;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;

class QuestionController extends Controller
{
    public function index()
    {
        $data = [];
        $likes = QuestionLike::all();
        //いいね数まで含めた変数
        $questions = Question::withCount('question_likes')->orderBy('created_at', 'desc')->paginate(10);

        //ユーザ名前を引っ張ってくる
        $users = Question::with('user:id,name')->get();
        $data = [
            'questions' => $questions,
            'likes' => $likes,
            'users' => $users,
        ];

        return view('test.nayami', $data);
    }


    public function ajaxlike(Request $request)
    {
        $id = Auth::user()->id;
        $question_id = $request->question_id;
        $like = QuestionLike::where('question_id', $question_id)->where('user_id', $id)->first();
        $question = Question::findOrFail($question_id);

        if ($like) {
            //likesテーブルのレコードを削除
            $like = QuestionLike::where('question_id', $question_id)->where('user_id', $id)->delete();
        } else {
            QuestionLike::create(['user_id' => $id, 'question_id' => $question_id]);
        }

        $questionLikesCount = $question->loadCount('question_likes')->question_likes_count;
        //これがajaxのdataとして渡される
        print($questionLikesCount);
    }

    public function nayami_add(Request $request)
    {
        return view('test.add');
    }

    public function nayami_create(Request $request)
    {
        $id = Auth::id();
        $param = [
            'title' => $request->title,
            'user_id' => $id,
            'content' => $request->main,

        ];
        DB::table('questions')->insert($param);
        return redirect('/test');
    }

    public function detail($id)
    {
        $posts = DB::table('questions')->get();
        $answer_questions = AnswerQuestion::withCount('answer_question_likes')->orderBy('created_at', 'desc')->where('question_id', $id)->paginate(10);
        $answers = DB::table('answer_questions')->where('question_id', $id)->get();

        //名前表示用
        $users = AnswerQuestion::with('user:id,name')->where('question_id', $id)->get();
        $nayami_users = Question::with('user:id,name')->get();

        $question = Question::findorFail($id);
        $likes = AnswerQuestionLike::all();
        return view('test.nayami_detail')->with(array('answer_questions' => $answer_questions, 'answers' => $answers, 'question' => $question, 'likes' => $likes,'nayami_users' => $nayami_users, 'users' => $users));
    }

    public function nayami_answer(Request $request)
    {
        $id = Auth::id();
        $items = DB::table('users')->where('id', $id)->first();
        $param = [
            'question_id' => $request->question_id,
            'user_id' => $id,
            'content' => $request->content
        ];
        DB::insert('insert into answer_questions (question_id, user_id, content) values (:question_id,:user_id,:content)', $param);

        return back();
    }

    public function answer_question_like(Request $request)
    {
        $id = Auth::user()->id;
        $answer_question_id = $request->answer_question_id;
        $like = AnswerQuestionLike::where('answer_question_id', $answer_question_id)->where('user_id', $id)->first();
        $answer_question = AnswerQuestion::findOrFail($answer_question_id);

        if ($like) {
            //likesテーブルのレコードを削除
            $like = AnswerQuestionLike::where('answer_question_id', $answer_question_id)->where('user_id', $id)->delete();
        } else {
            AnswerQuestionLike::create(['user_id' => $id, 'answer_question_id' => $answer_question_id]);
        }

        $answerquestionLikesCount = $answer_question->loadCount('answer_question_likes')->answer_question_likes_count;
        //これがajaxのdataとして渡される
        print($answerquestionLikesCount);
    }

    public function nayami_destroy($id)
    {
        #削除処理
        $greeting = Question::findOrFail($id);
        $greeting->delete();
        $data = Question::all();
        
        return redirect('/test');
    }
}
```


参考までに値が渡されるviewも載せておきます。
これで、質問投稿関連の機能は実装されるようになります。

###質問内容が一覧表示される画面

```php:nayami.blade.php

@extends('layouts.layout')
<!DOCTYPE html>
<html>

<head>
  <title>nayami</title>
  <meta name="csrf-token" content="{{ csrf_token() }}">
</head>

@section('content')

<div class="outer">
  <div class="inner1">

    <br>
    <h1>投稿された悩み一覧</h1>
    <br>

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">
  </div>

  <div class="inner2">
    @foreach($questions as $question)
    <div class="tw-block-parent">
      @auth
      @if((int)$question->user_id == Auth::user()->id)
      <div class="button2">
        <button class="btn btn-primary" data-toggle="modal" data-target="#modal-example{{$question->id }}">
          削除
        </button>
        <!-- 2.モーダルの配置 -->
        <div class="modal" id="modal-example{{$question->id }}" tabindex="-1">
          <div class="modal-dialog">
            <!-- 3.モーダルのコンテンツ -->
            <div class="modal-content">
              <!-- 4.モーダルのヘッダ -->
              <div class="modal-header">
                <p class="modal-title" id="modal-label">削除しますか？</p>
              </div>
              <!-- 6.モーダルのフッタ -->
              <div class="modal-footer">
                <form method="POST" action="{{route('destroy',['id' => $question->id])}}">
                  @csrf
                  @method('delete')
                  <button class="btn btn-danger" data-id="{{ $question->id }}" type="submit">削除する</button>
                </form>
                <button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
              </div>

            </div>
          </div>
        </div>
      </div>
      @endif
      @endauth

      <div class="timeline-TweetList-tweet">
        <div class="timeline-Tweet">
          <div class="timeline-Tweet-author">
            <div class="TweetAuthor">
              <a class="TweetAuthor-link" href="#channel"> </a>
              <span class="TweetAuthor-avatar">
                <div><i class="far fa-user"></i></div>
              </span>
              <form action="/test/mypage" method="post">
                @csrf
                <input type="submit" name="id" value="{{$users->find($question->id)->user->name}}">
                <span class="Icon Icon--verified"></span>
              </form>
              <!--<span class="TweetAuthor-name">{{$users->find($question->id)->user->name}}</span>-->
            </div>
          </div>
          <label>
            <a href="{{ action('QuestionController@detail', $question->id) }}">
              <div class="timeline-Tweet-text">
                <td>{{$question->title}}</td>
                <td>{{$question->content}}</td>
              </div>
            </a>
          </label>
          <div class="timeline-Tweet-metadata"><span class="timeline-Tweet-timestamp">{{$question->created_at}}</span></div>
          <ul class="timeline-Tweet-actions">
            @auth
            @if($likes->where('user_id',Auth::user()->id)->where('question_id',$question->id)->first())
            <li class="timeline-Tweet-action">
              <a class="js-like-toggle loved" href="" data-questionid="{{$question->id}}">
                <i class="fas fa-heart"></i>
              </a>
              <span class="likesCount">{{$question->question_likes_count}}</span>
            </li>
            @else
            <li class="timeline-Tweet-action">
              <a class="js-like-toggle" href="" data-questionid="{{$question->id}}">
                <i class="active far fa-heart"></i>
              </a>
              <span class="likesCount">{{$question->question_likes_count}}</span>
            </li>
            @endif
            @endauth

            @guest
            <p class="favorite-marke">
              <a class="js-like-toggle loved" href="" data-questionid="{{$question->id}}">
                <i class="fas fa-heart"></i>
              </a>
              <span class="likesCount">{{$question->question_likes_count}}</span>
            </p>
            @endguest

          </ul>
        </div>
      </div>
    </div>
    <br>
    @endforeach

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
    <script src="{{ mix('js/_questionlike.js') }}"></script>
  </div>
</div>
@endsection

```

###質問内容の詳細とアドバイス一覧表示画面

```php:nayami_detail.blade.php
<html>
@extends('layouts.layout')

<head>
    <meta name="csrf-token" content="{{ csrf_token() }}">
</head>


@section('content')
<div class="outer">
    <div class="inner2">
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
        <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">

        <h1>悩み詳細</h1>
        <br>
        <div class="timeline-TweetList-tweet">
            <div class="timeline-Tweet">
                <div class="timeline-Tweet-author">
                    <div class="TweetAuthor">
                        <a class="TweetAuthor-link" href="#channel"> </a>
                        <span class="TweetAuthor-avatar">
                            <div><i class="far fa-user"></i></div>
                        </span>

                        <span class="TweetAuthor-name">{{$nayami_users->find($question->id)->user->name}}</span>
                        <span class="Icon Icon--verified"></span>
                    </div>
                </div>
                <div class="timeline-Tweet-text">
                    <b>
                        タイトル：{{$question->title}}
                    </b>
                    <br><br>
                    本文：
                    {{$question->content}}
                </div>
                <div class="timeline-Tweet-metadata"><span class="timeline-Tweet-timestamp">{{$question->created_at}}</span></div>
                <ul class="timeline-Tweet-actions">
                    @if($likes->where('user_id',Auth::user()->id)->where('question_id',$question->id)->first())
                    <li class="timeline-Tweet-action">
                        <a class="js-like-toggle loved" href="" data-questionid="{{$question->id}}">
                            <i class="fas fa-heart"></i>
                        </a>
                        <span class="likesCount">{{$question->question_likes_count}}</span>
                    </li>
                    @else
                    <li class="timeline-Tweet-action">
                        <a class="js-like-toggle" href="" data-questionid="{{ $question->id }}">
                            <i class="active far fa-heart"></i>
                        </a>
                        <span class="likesCount">{{$question->question_likes_count}}</span>
                    </li>
                    @endif
                </ul>
            </div>
        </div>
        <br>

        <button class="btn btn-primary" data-toggle="modal" data-target="#modal-example">
            悩める子羊にアドバイス
        </button>
        <!-- 2.モーダルの配置 -->
        <div class="modal" id="modal-example" tabindex="-1">
            <div class="modal-dialog">
                <!-- 3.モーダルのコンテンツ -->
                <div class="modal-content">
                    <!-- 4.モーダルのヘッダ -->
                    <div class="modal-header">
                        <p class="modal-title" id="modal-label">アドバイスしよう</p>
                    </div>
                    <!-- 5.モーダルのボディ -->
                    <form method="post">
                    @csrf
                    <div class="modal-body">
                        <input type="hidden" name="question_id" value="{{$question->id}}">
                        <div><input type="text" name="content" class="form-control" required placeholder="アドバイス入力"></div>  
                    </div>
                    <!-- 6.モーダルのフッタ -->
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
                        <button type="submit" class="btn btn-primary">送信</button>
                    </div>
                    </form>
                </div>
            </div>
        </div>

        <br>
        <br>
        <br>
        <h2>アドバイス一覧</h2>
        @foreach($answer_questions as $answer_question)
        <div class="tw-block-parent">
            <div class="timeline-TweetList-tweet">
                <div class="timeline-Tweet">
                    <div class="timeline-Tweet-author">
                        <div class="TweetAuthor">
                            <a class="TweetAuthor-link" href="#channel"> </a>
                            <span class="TweetAuthor-avatar">
                                <div><i class="far fa-user"></i></div>
                            </span>
                            <form action="/test/mypage" method="post">
                                @csrf
                                <input type="submit" name="id" value="{{$users->find($answer_question->id)->user->name}}">
                                <span class="Icon Icon--verified"></span>
                            </form>
                        </div>
                    </div>
                    <div class="timeline-Tweet-text">
                        {{$answer_question->content}}
                    </div>
                    <div class="timeline-Tweet-metadata"><span class="timeline-Tweet-timestamp">{{$answer_question->created_at}}</span></div>
                    <ul class="timeline-Tweet-actions">

                        @if($likes->where('user_id',Auth::user()->id)->where('answer_question_id',$answer_question->id)->first())
                        <li class="timeline-Tweet-action">
                            <a class="js-like-toggle loved" href="" data-answerquestionid="{{$answer_question->id}}">
                                <i class="fas fa-heart"></i>
                            </a>
                            <span class="likesCount">{{$answer_question->answer_question_likes_count}}</span>
                        </li>
                        @else
                        <li class="timeline-Tweet-action">
                            <a class="js-like-toggle" href="" data-answerquestionid="{{$answer_question->id }}">
                                <i class="active far fa-heart"></i>
                            </a>
                            <span class="likesCount">{{$answer_question->answer_question_likes_count}}</span>
                        </li>
                        @endif

                    </ul>
                </div>
            </div>
        </div>
        @endforeach

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
        <script src="{{ mix('js/_answerquestionlike.js') }}"></script>
    </div>
</div>

@endsection

</html>
```

###質問投稿画面

```php:add.blade.php
<html>
@extends('layouts.layout')
@section('content')
<div class="outer">
    <div class="inner1">
        <h1>悩みを記入して送信</h1>
    </div>
    <br>
    <div class="inner2">
        <form action="/test/add" method="post">
            <table>
                @csrf
                <tr>
                    <th>title: </th>
                    <td><input type="text" name="title"></td>
                </tr>
                <tr>
                    <th>main: </th>
                    <td>
                        <textarea rows="10" cols="80" name="main" class="form-control"></textarea>
                    </td>
                </tr>
                <tr>
                    <th>
                    <td><input type="submit" value="send"></td>
                    </th>
                </tr>
            </table>
        </form>
    </div>
</div>
@endsection

</html>
```