#5 Modelの作成 ~laravel×AWSで掲示板を作ろう~

#laravel×AWSで掲示板を作ろう
本記事は、laravel×AWSの第5回です。
作ったサイト：<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)


#MVCモデルについて
手を動かす前にlaravelの考え方的なものを知っておく必要があるので簡単に書いておきます。laravelはMVCフレームワークと呼ばれ、「Model」「View」「Controller」の３つに役割分担させながらweb表示させています。
ざっくりと以下の認識です。
Model：データベース（情報源）
View：表示画面（箱）
Controller：表示画面に持ってくるデータを決定（監督）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832092/b581ed44-dc17-f1dc-420c-5f35a304d679.png)
引用元：<https://se-shine.net/what-mvc/>

#Eloquent ORM
データベース操作を柔軟にできるようにLaravelに含まれている機能です。
questionsテーブルから全データを取得する場合は下記のようになります。

```php
//通常の方法
use Illuminate\Support\Facades\DB;
$questions = DB::table('questions')->get();

//Eloquentを使った方法
use App\Question;
$questions = Question::all();
```

何のためにこんな機能があるのかというと、他テーブルとの紐づけをする必要が出てきたときに便利になるからです。（後ほど説明します）

laravelにおいてModelとデータベースのテーブル名の決め方にルールがあります。これはかなり大事で、この前提の下でlaravelさんは便利な機能を提供してくれているからです。（知らずに適当に名前を付けててかなり苦労しました。。）

Model名（単数形）⇔ テーブル名（複数形）

| モデル名      　  |     テーブル名  | 
|:-----------------|---------------- |
| Question         |  questions      |
| Tweet            |    tweets       |
| AnswerQuestion   |answer_questions |  
| AnswerTweet      |   answer_tweets | 
| QuestionLike   |quesition_likes |  
| TweetLike      |   tweet_likes | 
| AnswerQuestionLike   |answer_question_likes |  
| AnswerTweetLike      |   answer_tweet_likes | 


#Model作成手順
まずは以下のコマンドを打ち込んでください。

```
$php artisan make:model Question
```
すると、app直下にQuestion.phpが作成されます。
![app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832092/7fc0c80a-29d8-12fc-454a-59b221d9e42c.png)

これだけで、あとはコントローラでモデルを宣言するだけで、自動的にquestionsテーブルを認識してくれます。

```php
use App\Question;
$questions = Question::all();
```

テーブルの作り方は [データベース構築](https://qiita.com/surasurag/items/f9be44372c41f83cc543)で紹介してある通りですが、下記コマンドでモデル作成と同時に一括で作成できます。

```
php artisan make:model Question -m
```




#リレーションについて
各質問に対するいいねの数を参照する際の考え方を説明します。
投稿された質問に関する情報はquestionsテーブルに、質問内容に対するいいねに関する情報はquestion_likesテーブルで管理されています。
questionsテーブルとquestion_likesテーブルの構造は以下になっており、
「questionsテーブルのid」と「question_likesテーブルのquestion_id」で紐づけられています。![eloquent.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832092/dcd0bba0-e2e9-0da3-1678-cd1bc8763fb3.png)

よって、投稿された悩みに対するいいねの数を参照するには、「紐づけ作業」をしてあげる必要があります。
こういう時に、モデルを上手く使ってあげるととても便利です。
今回はQuestionモデルにおいて下記のように紐づけをしました。
hasmany, belongsToについては他を参照してください。
参考：<https://moripro.net/laravel-hasmany-belongsto/>

```php:Question.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Auth;
use App\QuestionLike;

class Question extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    //ここで紐づけしてあげる
    public function question_likes()
    {
        return $this->hasMany(QuestionLike::class);
    }
}
```

こうしてあげることで、Question::withCount('question_likes')とするだけで、
いいね数（question_likesテーブルにおける特定のquestion_idのデータ数）を自動的に数えてくれます。

```php:QuestionController.php
//function index部分のみ記載
class QuestionController extends Controller
{
    public function index()
    {
        $data = [];
        $likes = QuestionLike::all();
        //いいね数まで含めた変数　question_likes_count
        $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);
    }

(以下略)
```