Symfonyでタスク管理アプリ作ってみた

フレームワークの勉強のためにSymfony3でタスク管理アプリを作ってみました。まだ作ってる途中ですが、理解を深めるために作業内容をまとめてみます。少しは何かの参考になるかもしれません。

1.[コントローラ編](http://qiita.com/asaokamei/items/bdf36d6c6fb725661bfe)
2.[エンティティ編](http://qiita.com/asaokamei/items/94c8d49b2d864502bb2e)
3.[フォーム編](http://qiita.com/asaokamei/items/eb782eefb6a9a601a242)
4.[サービス編](http://qiita.com/asaokamei/items/1b3522dab11851be1614)
5.[番外編：GuardとEntityを使った認証](http://qiita.com/asaokamei/items/5122e398e4cc17c84429)

### 方針

作業を始めたときの最新バージョン、Symfony 3.2を利用します。

Symfonyフレームワークを覚えるのが目的なので、JavaScriptはjQueryを軽く使う程度で。古き良きウェブサイトを作ります（SPAではないです）。

### 参考

参考にしたのは[Symfonyのウェブサイト](http://symfony.com/doc/current/index.html)、それと前に購入しておいた「[基本からしっかり学ぶSymfony2入門](https://www.amazon.co.jp/dp/4774178039)」という本です。利用しているSymfonyはバージョン３ですが、Symfony2入門のコードはほとんど使えた気がします。Symfonyは想像以上に互換性を重視しているみたいです。

> 正直にいうと、Symfonyのサイトは読みづらい＆理解しづらいです。Symfony2入門があると理解が早いと思いました。

### インストール

次のようにコマンドを打ってください。

1. `git clone https://github.com/asaokamei/TaskComplete`
2. `cd TaskComplete`
3. `composer install`
4. `TaskComplete/var/sqlite`ディレクトリに書き込み権限があること。
5. `php bin/console doctrine:schema:update --force`

これで動きます。最低限の初期データを登録するには、

1. `run php bin/console server:run`
2. ブラウザーで次のURLにアクセス： `http://localhost:8000/settings/initialize`
3. フォームにチェックを入れてボタンをクリック。

> セットアップでDBにデータを書き込むより、[DoctrineFixturesBundle](http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html)を使うほうがいいのだろうけれど。

データ構造
----

少し複雑な構造のアプリを作ってみたかったので、データは３層構造にしました。

### ER図

![タスク管理システムのER図](https://qiita-image-store.s3.amazonaws.com/0/31171/9ab76342-3ccb-1b62-38ec-70c682670c7b.png)


```
task_project ＞ task_group ＞ task_task
```

という構造になってます。

### プロジェクト詳細画面

プロジェクトの詳細画面を見ると分かりやすいと思います。これは「TaskComplete Application」というプロジェクトの詳細です。

![プロジェクトの詳細](https://qiita-image-store.s3.amazonaws.com/0/31171/bb140f6d-f605-68ed-2054-98c31ce57017.png)

プロジェクト内に複数のターゲット（tasksとtestがあります）があり、さらに複数の作業項目があります。

```
project ＞ targets ＞ tasks
```

> DB上ではターゲットはGroupになります。途中で名前を変えたのですが、DBまで変更してない…

ターゲットですが、イメージとしてはアジャイルのスプリントみたいな区切りで、だいたい１週間〜１ヶ月ぐらいの作業量というイメージです。

サマリ画面
----

わざわざ３層構造にしたのは、色々な角度から仕事のプライオリティや進捗具合を見たかったからです。

### By-Target画面

ターゲットをずらりと日付順に並べます。今、もっとも緊急の作業は何かひと目で分かるページです。

![By-Target画面](https://qiita-image-store.s3.amazonaws.com/0/31171/a629e80d-de09-f40d-d788-e3a1adc8e0da.png)

### By-Date画面

作業項目をずらりと日付順に並べます。今日や明日に行いたい作業を把握できます。

![By-Date画面](https://qiita-image-store.s3.amazonaws.com/0/31171/144f96d8-4316-1530-097f-9c177ef0cc70.png)

個人的なポイントは、24時間以内に終了したタスクは表示してあること。これで、達成感を味わいたいなと。

> DB設計してたときは退屈だとしか思えませんでしたが、画面を作ってみたら俄然やる気が出てきました。

その他、色々
----

### Symfonyフレームワーク

現状でのSymfony最新版、バージョン3.2.1を利用してます。[インストールはcomposer使った](http://symfony.com/doc/current/setup.html)記憶があります。

大事な点として、フレームワークと一緒に[SensioFrameworkExtraBundle](http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/index.html)を利用しています。Symfonyの開発元が作っているバンドルで、Routeアノテーションを利用できるようになります。

ORMとしては、Doctrine2を利用します。[Symfonyでは標準のようなORM](http://symfony.com/doc/current/doctrine.html)ですね。また、データベースにはsqliteを利用してます。マイグレーションのために、`doctrine/doctrine-migrations-bundle`もインストールしました。

### アーキテクチャー

開発するにあたって、レイヤーアーキテクチャーを念頭に作ってみました。（参考：[中規模Web開発のためのMVC分割とレイヤアーキテクチャ](http://qiita.com/yuku_t/items/961194a5443b618a4cac)）。

アプリケーションを大きく４つの層から考えるのですが、フレームワークでのクラスとの対応をシンプルに書くと、こんな感じになるでしょう。

|レイヤー|対応するクラスやパッケージ|
|:-----------|:------------|
|プレゼンテーション層|twigテンプレート|
|アプリケーション層|controller class|
|ドメイン層|entity class|
|インフラストラクチャ層|Doctrine2 ORM|

このテーブルにあるクラスやサービス以外に、大量のクラスを書いてくことになりますが、作ってるクラスが属するレイヤーはどれかを考えて、上位のレイヤーに依存しないことを念頭に置いて開発します。