RoomClipでインターンをしている松永です。

今回はこの『RoomClip開発者ブログ』を開発した話をします。

Yii2フレームワーク

タイトルにもある通り、このブログはYii2というフレームワークを用いて一から実装されています。ちなみにRoomClipの開発に使用されているのはCodeIgniterです。

Yii2はPHPのMVCフレームワークのひとつで、高速であることやセキュアであることを売りにしているようです(他のフレームワークがそうでないかというと、そんなこともないと思いますが)。 実際に使ってみると、キャッシュを簡単に使用できたりCodeceptionでのテストをサポートしていたりと非常に開発をしやすい印象を受けました。サービスの規模に応じての拡張が容易であることも魅力的でした。

このYii2にはGiiというコード生成を行うためのExtensionがあり、これを用いるとDBテーブルに紐付いたモデルクラスやCRUDコードなどをGUIを通して生成することができます。また、テーブル構造の変更を考慮してクエリなどは生成したモデルクラスを継承したクラスに記述をしています。

Untitled

Yii2についてのより詳細な説明はこちらを参照してください。

※ 2024年現在はNotionに移設

開発

既存のコードに変更を加えたり機能を追加することはありましたが、ほぼ何もない状態からWebアプリケーションの開発を行うのは僕にとって初めての経験でした。 知識が足りないことも多く、細かなソフトウェア設計には頭を悩まされましたが、他のエンジニアに助けてもらいつつ実装を進めていきました。

コーディング規約は基本的にYii2のコードに合わせるように定めました。Giiでコードを生成するとDBのカラム名と生成される変数名が同じになるため、カラム名もキャメルケースで統一しています。

モデルクラス内のクエリ文はできるだけcreateCommandを使用して書きたいという思いがあったのですが、そのままだと目的のクラスのオブジェクトではなく連想配列として値が返ってきてしまいます。また、数値を期待していてもクエリを通すと文字列として返ってくるため型のチェックと変換を行いたいです。

そこで、以下のようなtraitを作成し、モデルクラスに与えることでこの2つの問題を解決しました。

trait ORMapper
{
    private static function readOne($query)
    {
        $result = $query->readObject(get_class($this), []);
        if ($result === false) {
            return false;
        }

        foreach ($result->getValidators() as $validator) {

            if ($validator instanceof \\yii\\validators\\NumberValidator) {

                foreach ((array)$validator->attributes as $attribute) {
                    if (isset($result[$attribute])) {
                        $result[$attribute] = $validator->integerOnly
                        	 ? (integer)$result[$attribute]
                        	 : (float)$result[$attribute];
                    }
                }

            } elseif ($validator instanceof \\yii\\validators\\BooleanValidator) {

                foreach ((array)$validator->attributes as $attribute) {
                    if (isset($result[$attribute])) {
                        $result[$attribute] = (boolean)$result[$attribute];
                    }
                }

            } elseif ($validator instanceof \\yii\\validators\\StringValidator) {

                foreach ((array)$validator->attributes as $attribute) {
                    if (isset($result[$attribute])) {
                        $result[$attribute] = (string)$result[$attribute];
                    }
                }
            }
        }

        return $result;
    }
}

view rawORMapper hosted with ❤ by GitHub