Help us understand the problem. What is going on with this article?

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

laravel×AWSで掲示板を作ろう

本記事は、laravel×AWSの第6回です。
作ったサイト:https://vible.jp

【参照】
1. 完成形イメージ
2. AWSサーバを立てる(工事中)
3. サーバにlaravelを導入してRDSと連携する(工事中)
4. データベース構築
5. Modelの作成
6. Controllerの作成
7. いいね機能の実装
8. ルーティングの実装

Controllerとは?

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

Controller作成手順

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

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

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

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

$ php artisan make:controller Question

これでapp\Http\Controllers直下にファイルが作成されました。
controller.png

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

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

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

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も載せておきます。
これで、質問投稿関連の機能は実装されるようになります。

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

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

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

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>

質問投稿画面

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>
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away