チャットアプリで、1グループのメッセージ数上限を50件にする(Laravel)

#はじめに
初心者による初心者向けの記事です。
陥りやすい様々な苦手分野も交えて書いてみました。
「collectionと配列の違い」「モデルインスタンスってなんやねん！」「クエリビルダとかメソッドとかわからん！」「ネットで```count()```関数について調べてから使ったのに、エラーになる！」など。
#このように実装しようと思った背景
実用的なチャットアプリを作りたいため、今回の実装をしました。
テーブル関係はgroups hasmany messagesの1対多です。
私はAjax通信のリアルタイムチャットアプリを作成しています。LINEのグループチャット的なものです。
トークルームのAjaxは、では５秒おき（```setTimeout("get_messageC()",5000);```）にそのグループの全メッセージを取得し、表示してあるメッセージを全部消して(```.remove();```)全部書き足す（```.append(html);```）という実装をしています。
しかしこれでは、メッセージが1000,2000と増えるごとに動作が重くなってしまいます。よって、1グループメッセージは50件までしか保存されないような設計にしました。そうすれば最大でも50件しか書き換えと表示が行われません。
#やること
★メッセージ送信アクション時に、そのgroup_idと関連づいたmessageの数を数える（ここでcollectionと配列の違いを理解しとく必要がある）→
★50件以上あるなら、上位50件以外のメッセージは削除する(ここでモデルインスタンスなのかDBインスタンスなのか把握しておく必要がある)

下図messageテーブルです。ターミナルにてmysqlで出しました。見づらいですが、messagesテーブルのカラムにgroup_idがあります。user_idはグループ作成者です。いざという時の拡張性を考えて入れときました。
<img width="1440" alt="スクリーンショット 2020-05-30 11.50.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487894/d9b17859-5624-096f-3a0e-a44c4ff7c3d8.png">
#collectionと配列の違い
collectionはLaravelが提供する高機能な配列です。一方で配列はみなさんがよく見かけるphpの「the・普通の配列」です。
データをインスタンス化した時はcollectionであることが多いです。例えば下記のようにモデルをインスタンス化した時。
例：```$apple = new Apple;```
下記のように自分で配列を作った時は、紛れもなくphpの配列です。
例：```$apple = array('iphone','macbook' ,'ipad');```
###違いを理解すべき瞬間
厄介なのは、「配列の要素数を数えるcount関数」1つとっても、collectionと配列で文法が異なることです。先ほどの```$apple```を例に取りましょう。
collectionの場合```$count = $apple->count(); ```
配列の場合```$count = count($apple);```
ちなみに配列関数```count()```をcollectionに適用すると以下のようなエラーが出ます。
```ErrorException (E_WARNING) 
count(): Parameter must be an array or an object that implements Countable
```
「count()関数は引数は配列かオブジェクトじゃないとダメですよ〜」ということですね。collectionを配列とみなしていないようです。
ちなみに僕もなんのインスタンスがcollectionになるのか、というのは把握していません。エラー文見てその都度判断してます。
#書いたコード
先にクラスをuseしちゃいましょう。自分のコントローラーにあるものをコピペします。
###今回使用するクラス
注目すべき箇所は「★」をつけてます。今回は★をuseしておけば問題ないと思います。

```php:GroupController.php
<?php

namespace App\Http\Controllers\User;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB; //★
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Auth;
use Illuminate\Support\Facades\Hash;
use App\User;
use App\Follow;
use Abraham\TwitterOAuth\TwitterOAuth;
use App\Group;
use App\Message; //★
use Illuminate\Support\Facades\Log;
use Storage; 
```


```php:GroupController.php@send
///まず現在チャットしているgroupのメッセージ数を全て取得します。
    $count = $message->where('group_id',$_POST['group_id'])->count();
///その数が50を超えているなら、
    if ($count > 50) {
///現在チャットしてるグループがhasするmessageのidを取得するためにやはりまずメッセージを取得します
      $deleteid = DB::table('messages')
      ->where('group_id', $_POST['group_id'])
///それの並び順を古い順から新しい順に変えます。
      ->orderBy('id','desc')
///messageデータを50件のみ取得します（新しい順なので最新50件）。
      ->take(50)
///idのみ抽出します（必要ないけど、動作軽くなるかなーと思って）
      ->pluck('id')
//最新50件のなかで最も古いメッセージのidを取得。これで$deleteidに最も古いメッセージのidを入れました。
      ->min();

      Message::where('group_id',$_POST['group_id'])
//$deleteidより古いメッセージは全て削除。
      ->where('id','<',$deleteid)->delete();
    }
```
このコードより前で```$message = new Message;```しました。つまり```$message```は、Messageモデルのインスタンスです。```group_id```はAjaxの```type: "POST",```で送信しているので、```$_POST['group_id']```で受け取ります。```type: "GET",```の場合やそもそもtype指定してない場合は```$_GET['group_id']```で受け取ってください。type指定しないと自動で```type: "GET",```になるので。
###tips
なぜ```$message```があるにもかかわらず```if(){}```内でわざわざ```DB::table('messages');```しているのか。なぜ```$message```を使用しないのか。
それは、```$message```はcollectionだからです。```Message```モデルのインスタンスなのでcollectionになります。
クエリビルダのメソッドを使いたいです。```->orderBy()```と```->take()```と```->pluck()```を使いたいです。DBのインスタンスじゃないとクエリビルダメソッドは使えません。
ちなみに```use Illuminate\Support\Facades\DB; //★```クラスをインスタンス化してます。

また、```$message```にクエリメソッドをしようすると、```Object of class Illuminate\Database\Eloquent\Builder could not be converted to string```エラーが出ます。
一番下でまたクラス呼んでいますが、なぜそうしたか自分でもわかりません。昨日の自分に問い質したいです。
``` Message::where('group_id',$_POST['group_id'])
      ->where('id','<',$deleteid)->delete();```
#最後に
よく「ドキュメント読め」とか「オブジェクト指向を理解しろ」と言われますが、それが全てだと僕は思いません。
ドキュメントが理解できるようになったのは学習開始5ヶ月目とかですし、平均1日6時間とか勉強した挙句のそれです。
僕が要領悪いだけかもしれませんが、是非僕のような初心者の方の役に立てたら幸いです。