Symfony2チュートリアル/02/

#概要
データベースを作成し中身を入れてブラウザで表示するところまで行っていく。

#目次
- データベース
- スキーマ
- The ORM
- ブラウザーで確認する

#データモデル
###データベース
データベース接続パラメータを定義するには、（MySQL使用） app/config/parameters.yml ファイルを編集する必要があるみたいよ。

```
app/config/parameters.yml

parameters:
    database_host: 127.0.0.1
    database_port: null
    database_name: jobeet
    database_user: root
    database_password: ******（自分のPC設定）
...
```

データベースを作成しようとします。エラーに遭遇します。MySQLの立ち上げ忘れなので、立ち上げます。

```
$ php app/console doctrine:database:create

                                                                             
  [Doctrine\DBAL\Exception\ConnectionException]                              
  An exception occured in driver: SQLSTATE[HY000] [2002] Connection refused  
                                                                             

                                             
  [Doctrine\DBAL\Driver\PDOException]        
  SQLSTATE[HY000] [2002] Connection refused  
                                             

                                             
  [PDOException]                             
  SQLSTATE[HY000] [2002] Connection refused  
                                             

doctrine:database:create [--shard SHARD] [--connection [CONNECTION]] [--if-not-exists] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-s|--shell] [--process-isolation] [-e|--env ENV] [--no-debug] [--] <command>
```

```
$ mysql.server start
Starting MySQL
.. SUCCESS! 
```

よしこれで立ち上がるはずなので再度試すものの怒られる。

```
$ php app/console doctrine:database:create

                                                                                    
  [Doctrine\DBAL\Exception\ConnectionException]                                     
  An exception occured in driver: SQLSTATE[HY000] [2002] No such file or directory  
                                                                                    

                                                    
  [Doctrine\DBAL\Driver\PDOException]               
  SQLSTATE[HY000] [2002] No such file or directory  
                                                    

                                                    
  [PDOException]                                    
  SQLSTATE[HY000] [2002] No such file or directory  
                                                    

doctrine:database:create [--shard SHARD] [--connection [CONNECTION]] [--if-not-exists] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-s|--shell] [--process-isolation] [-e|--env ENV] [--no-debug] [--] <command>
```

何かの設定がおかしい。下記のサイトを見てみるとapp/config/parameters.ymlが間違っているっぽいので、修正する。
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11128812741

`「127.0.0.1からlocalhostに変えて試してみてください」`ということらしいので、修正してみる。

```
app/config/parameters.yml

# This file is auto-generated during the composer install
parameters:
    database_host: localhost
    database_port: null
    database_name: jobeet
    database_user: root
    database_password: ****** （自分の環境に合わせて）
    mailer_transport: smtp
    mailer_host: localhost
    mailer_user: null
    mailer_password: null
    secret: 1930c1d803af0c0bd2c4c1b6c8db8c9248835da0

```

再度データベース作成のコマンドを叩くと無事に作成完了。


```
$ php app/console doctrine:database:create
Created database `jobeet` for connection named default
```


###スキーマ
Doctrine にオブジェクトを教えるために、「メタデータ」ファイルを作成していく。
まずは`src/Ibw/JobeetBundle/Resources/config`ディレクトリの中に doctrineという名前のディレクトリを作成する。その中にCategory.orm.yml、Job.orm.ymlとAffiliate.orm.ymlを作成して中身を下記のようにする。

```
#src/Ibw/JobeetBundle/Resources/config/doctrine/Category.orm.yml

Ibw\JobeetBundle\Entity\Category:
    type: entity
    table: category
    id:
        id:
            type: integer
            generator: { strategy: AUTO }
    fields:
        name:
            type: string
            length: 255
            unique: true
    oneToMany:
        jobs:
            targetEntity: Job
            mappedBy: category
    manyToMany:
        affiliates:
            targetEntity: Affiliate
            mappedBy: categories
```

```
#src/Ibw/JobeetBundle/Resources/config/doctrine/Job.orm.yml

Ibw\JobeetBundle\Entity\Job:
    type: entity
    table: job
    id:
        id:
            type: integer
            generator: { strategy: AUTO }
    fields:
        type:
            type: string
            length: 255
            nullable: true
        company:
            type: string
            length: 255
        logo:
            type: string
            length: 255
            nullable: true
        url:
            type: string
            length: 255
            nullable: true
        position:
            type: string
            length: 255
        location:
            type: string
            length: 255
        description:
            type: text
        how_to_apply:
            type: text
        token:
            type: string
            length: 255
            unique: true
        is_public:
            type: boolean
            nullable: true
        is_activated:
            type: boolean
            nullable: true
        email:
            type: string
            length: 255
        expires_at:
            type: datetime
        created_at:
            type: datetime
        updated_at:
            type: datetime
            nullable: true
    manyToOne:
        category:
            targetEntity: Category
            inversedBy: jobs
            joinColumn:
                name: category_id
                referencedColumnName: id
    lifecycleCallbacks:
        prePersist: [ setCreatedAtValue ]
        preUpdate: [ setUpdatedAtValue ]
```

```
#src/Ibw/JobeetBundle/Resources/config/doctrine/Affiliate.orm.yml

Ibw\JobeetBundle\Entity\Affiliate:
    type: entity
    table: affiliate
    id:
        id:
            type: integer
            generator: { strategy: AUTO }
    fields:
        url:
            type: string
            length: 255
        email:
            type: string
            length: 255
            unique: true
        token:
            type: string
            length: 255
        is_active:
            type: boolean
            nullable: true
        created_at:
            type: datetime
    manyToMany:
        categories:
            targetEntity: Category
            inversedBy: affiliates
            joinTable:
                name: category_affiliate
                joinColumns:
                    affiliate_id:
                        referencedColumnName: id
                inverseJoinColumns:
                    category_id:
                        referencedColumnName: id
    lifecycleCallbacks:
        prePersist: [ setCreatedAtValue ]
```

###The ORM
Doctrine は以下のコマンドを使用してオブジェクトを定義するクラスを生成します。

```
$ php app/console doctrine:generate:entities IbwJobeetBundle

Generating entities for bundle "IbwJobeetBundle"
  > backing up Affiliate.php to Affiliate.php~
  > generating Ibw\JobeetBundle\Entity\Affiliate
  > backing up Category.php to Category.php~
  > generating Ibw\JobeetBundle\Entity\Category
  > backing up Job.php to Job.php~
  > generating Ibw\JobeetBundle\Entity\Job
```

src/Ibw/JobeetBundle/Entity/Job.phpで`created_at`と`updated_at`に以下のように修正する。Affiliate.phpも修正する。

```
#src/Ibw/JobeetBundle/Entity/Job.php

// ...

    /**
     * @ORM\PrePersist
     */
    public function setCreatedAtValue()
    {
        if(!$this->getCreatedAt()) {
            $this->created_at = new \DateTime();
        }
    }

    /**
     * @ORM\PreUpdate
     */
    public function setUpdatedAtValue()
    {
        $this->updated_at = new \DateTime();
    }
```


```
src/Ibw/JobeetBundle/Entity/Affiliate.php

// ...

    /**
     * @ORM\PrePersist
     */
    public function setCreatedAtValue()
    {
        $this->created_at = new \DateTime();
    }

// ...
```

これによって、オブジェクトの保存または更新をするときに、 Doctrineが`created_at`を設定し`updated_at`を更新するようになる。
アップデートされるものを確認していくと大丈夫そう。

```
$ php app/console doctrine:schema:update --dump-sql

CREATE TABLE affiliate (id INT AUTO_INCREMENT NOT NULL, url VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, token VARCHAR(255) NOT NULL, is_active TINYINT(1) DEFAULT NULL, created_at DATETIME NOT NULL, UNIQUE INDEX UNIQ_597AA5CFE7927C74 (email), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE category_affiliate (affiliate_id INT NOT NULL, category_id INT NOT NULL, INDEX IDX_9E1A77FF9F12C49A (affiliate_id), INDEX IDX_9E1A77FF12469DE2 (category_id), PRIMARY KEY(affiliate_id, category_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE category (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_64C19C15E237E06 (name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE job (id INT AUTO_INCREMENT NOT NULL, category_id INT DEFAULT NULL, type VARCHAR(255) DEFAULT NULL, company VARCHAR(255) NOT NULL, logo VARCHAR(255) DEFAULT NULL, url VARCHAR(255) DEFAULT NULL, position VARCHAR(255) NOT NULL, location VARCHAR(255) NOT NULL, description LONGTEXT NOT NULL, how_to_apply LONGTEXT NOT NULL, token VARCHAR(255) NOT NULL, is_public TINYINT(1) DEFAULT NULL, is_activated TINYINT(1) DEFAULT NULL, email VARCHAR(255) NOT NULL, expires_at DATETIME NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME DEFAULT NULL, UNIQUE INDEX UNIQ_FBD8E0F85F37A13B (token), INDEX IDX_FBD8E0F812469DE2 (category_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
ALTER TABLE category_affiliate ADD CONSTRAINT FK_9E1A77FF9F12C49A FOREIGN KEY (affiliate_id) REFERENCES affiliate (id);
ALTER TABLE category_affiliate ADD CONSTRAINT FK_9E1A77FF12469DE2 FOREIGN KEY (category_id) REFERENCES category (id);
ALTER TABLE job ADD CONSTRAINT FK_FBD8E0F812469DE2 FOREIGN KEY (category_id) REFERENCES category (id);
```

```
$ php app/console doctrine:schema:update --force

Updating database schema...
Database schema updated successfully! "7" queries were executed
```

これでテーブルが作成された。
一応mysqlで確認をしておく。

```
mysql> use jobeet
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables
    -> ;
+--------------------+
| Tables_in_jobeet   |
+--------------------+
| affiliate          |
| category           |
| category_affiliate |
| job                |
+--------------------+
4 rows in set (0.01 sec)


```

テーブルの中身もどうやらあるらしい。

```
mysql> SHOW COLUMNS FROM job;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| category_id  | int(11)      | YES  | MUL | NULL    |                |
| type         | varchar(255) | YES  |     | NULL    |                |
| company      | varchar(255) | NO   |     | NULL    |                |
| logo         | varchar(255) | YES  |     | NULL    |                |
| url          | varchar(255) | YES  |     | NULL    |                |
| position     | varchar(255) | NO   |     | NULL    |                |
| location     | varchar(255) | NO   |     | NULL    |                |
| description  | longtext     | NO   |     | NULL    |                |
| how_to_apply | longtext     | NO   |     | NULL    |                |
| token        | varchar(255) | NO   | UNI | NULL    |                |
| is_public    | tinyint(1)   | YES  |     | NULL    |                |
| is_activated | tinyint(1)   | YES  |     | NULL    |                |
| email        | varchar(255) | NO   |     | NULL    |                |
| expires_at   | datetime     | NO   |     | NULL    |                |
| created_at   | datetime     | NO   |     | NULL    |                |
| updated_at   | datetime     | YES  |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+
17 rows in set (0.00 sec)
```

テーブルの中身はできているが、まだデータは何も入っていないので初期データをいれていく。

```
mysql> select * from job;
Empty set (0.00 sec)
```

composer.json ファイルの require セクションに以下を追加する。

```
// ...
    "require": {
        // ...
        "doctrine/doctrine-fixtures-bundle": "dev-master",
        "doctrine/data-fixtures": "dev-master"
    },

// ...
```

ベンダライブラリを更新します。php5.5を使っていたら怒られたので、php5.6に切り替える。

```
$ php composer.phar update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for doctrine/data-fixtures dev-master -> satisfiable by doctrine/data-fixtures[dev-master].
    - doctrine/data-fixtures dev-master requires php ^5.6 || ^7.0 -> your PHP version (5.5.38) does not satisfy that requirement.
```

一度pho5.5のバージョンをunlinkする。

```
$ brew unlink php55
Unlinking /usr/local/Cellar/php55/5.5.38_11... 17 symlinks removed
```

5.6をインストールする。

```
$ brew install php56
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 3 taps (caskroom/cask, homebrew/core, homebrew/services).
==> New Formulae
druid                                                                                                     jhipster
==> Updated Formulae
ammonite-repl             colordiff                 fop                       libuv                     nghttp2                   qt                        strongswan                yaz
aws-sdk-cpp               cromwell                  freeradius-server         libvidstab                node                      radare2                   terragrunt                yle-dl
awscli                    dmenu                     gmic                      logtalk                   node-build                rocksdb                   tmux
babl                      docker-credential-helper  grafana                   mame                      pachi                     rom-tools                 typescript
bear                      fluent-bit                grails                    mpg123                    pgpdump                   sbcl                      wartremover
ckan                      fonttools                 highlight                 mutt                      qcachegrind               shc                       xmount

...
```

再度`php composer.phar update`を試す。

```
$ php composer.phar update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 0 updates, 0 removals
Generating autoload files
> Incenteev\ParameterHandler\ScriptHandler::buildParameters
Updating the "app/config/parameters.yml" file
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache

 // Clearing the cache for the dev environment with debug true                                                          

                                                                                                                        
 [OK] Cache for the "dev" environment (debug=true) was successfully cleared.                                            
                                                                                                                        

> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installAssets

 Trying to install assets as relative symbolic links.

 --- -------------------------- ------------------ 
      Bundle                     Method / Error    
 --- -------------------------- ------------------ 
  ✔   FrameworkBundle            relative symlink  
  ✔   SensioDistributionBundle   relative symlink  
 --- -------------------------- ------------------ 

                                                                                                                        
 [OK] All assets were successfully installed.                                                                           
                                                                                                                        

> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installRequirementsFile
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::prepareDeploymentTarget
```

今度はうまくいきました。app/AppKernel.phpにバンドルDoctrineFixturesBundleを登録する。

```
app/AppKernel.php

// ...

public function registerBundles()
{
    $bundles = array(
        // ...
        new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle()
    );

    // ...
}
```

今ではすべてがセットアップされ、データをロードするために、バンドル内のsrc/Ibw/JobeetBundle/DataFixtures/ORMという名前の新しいフォルダに、いくつかの新しいクラスを作成します。

```
src/Ibw/JobeetBundle/DataFixtures/ORM/LoadCategoryData.php

<?php
namespace Ibw\JobeetBundle\DataFixtures\ORM;

use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Ibw\JobeetBundle\Entity\Category;

class LoadCategoryData extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $em)
    {
        $design = new Category();
        $design->setName('Design');

        $programming = new Category();
        $programming->setName('Programming');

        $manager = new Category();
        $manager->setName('Manager');

        $administrator = new Category();
        $administrator->setName('Administrator');

        $em->persist($design);
        $em->persist($programming);
        $em->persist($manager);
        $em->persist($administrator);
        $em->flush();

        $this->addReference('category-design', $design);
        $this->addReference('category-programming', $programming);
        $this->addReference('category-manager', $manager);
        $this->addReference('category-administrator', $administrator);
    }

    public function getOrder()
    {
        return 1; // the order in which fixtures will be loaded
    }
}
```

```
src/Ibw/JobeetBundle/DataFixtures/ORM/LoadJobData.php

<?php
namespace Ibw\JobeetBundle\DataFixtures\ORM;

use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Ibw\JobeetBundle\Entity\Job;

class LoadJobData extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $em)
    {
         $job_sensio_labs = new Job();
         $job_sensio_labs->setCategory($em->merge($this->getReference('category-programming')));
         $job_sensio_labs->setType('full-time');
         $job_sensio_labs->setCompany('Sensio Labs');
         $job_sensio_labs->setLogo('sensio-labs.gif');
         $job_sensio_labs->setUrl('http://www.sensiolabs.com/');
         $job_sensio_labs->setPosition('Web Developer');
         $job_sensio_labs->setLocation('Paris, France');
         $job_sensio_labs->setDescription('You\'ve already developed websites with symfony and you want to work with Open-Source technologies. You have a minimum of 3 years experience in web development with PHP or Java and you wish to participate to development of Web 2.0 sites using the best frameworks available.');
         $job_sensio_labs->setHowToApply('Send your resume to fabien.potencier [at] sensio.com');
         $job_sensio_labs->setIsPublic(true);
         $job_sensio_labs->setIsActivated(true);
         $job_sensio_labs->setToken('job_sensio_labs');
         $job_sensio_labs->setEmail('job@example.com');
         $job_sensio_labs->setExpiresAt(new \DateTime('+30 days'));
         $job_extreme_sensio = new Job();
         $job_extreme_sensio->setCategory($em->merge($this->getReference('category-design')));
         $job_extreme_sensio->setType('part-time');
         $job_extreme_sensio->setCompany('Extreme Sensio');
         $job_extreme_sensio->setLogo('extreme-sensio.gif');
         $job_extreme_sensio->setUrl('http://www.extreme-sensio.com/');
         $job_extreme_sensio->setPosition('Web Designer');
         $job_extreme_sensio->setLocation('Paris, France');
         $job_extreme_sensio->setDescription('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in.');
         $job_extreme_sensio->setHowToApply('Send your resume to fabien.potencier [at] sensio.com');
         $job_extreme_sensio->setIsPublic(true);
         $job_extreme_sensio->setIsActivated(true);
         $job_extreme_sensio->setToken('job_extreme_sensio');
         $job_extreme_sensio->setEmail('job@example.com');
         $job_extreme_sensio->setExpiresAt(new \DateTime('+30 days'));

         $em->persist($job_sensio_labs);
         $em->persist($job_extreme_sensio);
         $em->flush();
    }

    public function getOrder()
    {
        return 2; // the order in which fixtures will be loaded
    }
}
```

fixtures が一度書き込まれたら、コマンドラインの doctrine:fixtures:load コマンドを使用して、それらをロードする。

```
$ php app/console doctrine:fixtures:load
```

一度データを確認してみると、確かに入っている。

```
mysql> select * from job;
+----+-------------+-----------+----------------+--------------------+--------------------------------+---------------+---------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------+--------------------+-----------+--------------+-----------------+---------------------+---------------------+------------+
| id | category_id | type      | company        | logo               | url                            | position      | location      | description                                                                                                                                                                                                                                                                         | how_to_apply                                         | token              | is_public | is_activated | email           | expires_at          | created_at          | updated_at |
+----+-------------+-----------+----------------+--------------------+--------------------------------+---------------+---------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------+--------------------+-----------+--------------+-----------------+---------------------+---------------------+------------+
|  1 |           2 | full-time | Sensio Labs    | sensio-labs.gif    | http://www.sensiolabs.com/     | Web Developer | Paris, France | You've already developed websites with symfony and you want to work with Open-Source technologies. You have a minimum of 3 years experience in web development with PHP or Java and you wish to participate to development of Web 2.0 sites using the best frameworks available.    | Send your resume to fabien.potencier [at] sensio.com | job_sensio_labs    |         1 |            1 | job@example.com | 2017-07-01 12:31:16 | 2017-06-01 12:31:16 | NULL       |
|  2 |           1 | part-time | Extreme Sensio | extreme-sensio.gif | http://www.extreme-sensio.com/ | Web Designer  | Paris, France | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in. | Send your resume to fabien.potencier [at] sensio.com | job_extreme_sensio |         1 |            1 | job@example.com | 2017-07-01 12:31:16 | 2017-06-01 12:31:16 | NULL       |
+----+-------------+-----------+----------------+--------------------+--------------------------------+---------------+---------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------+--------------------+-----------+--------------+-----------------+---------------------+---------------------+------------+
2 rows in set (0.00 sec)
```

###ブラウザーで確認する
新しいコントローラー`src/Ibw/JobeetBundle/Controllers/JobController.php`を作成する。

```
$ php app/console doctrine:generate:crud --entity=IbwJobeetBundle:Job --route-prefix=ibw_job --with-write --format=yml

                                           
  Welcome to the Doctrine2 CRUD generator  
                                           


This command helps you generate CRUD controllers and templates.

First, give the name of the existing entity for which you want to generate a CRUD
(use the shortcut notation like AcmeBlogBundle:Post)

The Entity shortcut name [IbwJobeetBundle:Job]: IbwJobeetBundle:Job

By default, the generator creates two actions: list and show.
You can also ask it to generate "write" actions: new, update, and delete.

Do you want to generate the "write" actions [yes]? 

Determine the format to use for the generated CRUD.

Configuration format (yml, xml, php, or annotation) [yml]: 

Determine the routes prefix (all the routes will be "mounted" under this
prefix: /prefix/, /prefix/new, ...).

Routes prefix [/ibw_job]: 

                             
  Summary before generation  
                             

You are going to generate a CRUD controller for "IbwJobeetBundle:Job"
using the "yml" format.

Do you confirm generation [yes]? 

                   
  CRUD generation  
                   

  created ./src/Ibw/JobeetBundle/Controller//JobController.php
  created ./app/Resources/views/job/
  created ./app/Resources/views/job/index.html.twig
  created ./app/Resources/views/job/show.html.twig
  created ./app/Resources/views/job/new.html.twig
  created ./app/Resources/views/job/edit.html.twig
  created ./src/Ibw/JobeetBundle/Tests/Controller/
  created ./src/Ibw/JobeetBundle/Tests/Controller//JobControllerTest.php
  created ./src/Ibw/JobeetBundle/Resources/config/routing/
  created ./src/Ibw/JobeetBundle/Resources/config/routing/job.yml
Generating the CRUD code: OK
  created ./src/Ibw/JobeetBundle/Form/
  created ./src/Ibw/JobeetBundle/Form/JobType.php
Generating the Form code: OK
Updating the routing: Confirm automatic update of the Routing [yes]? 
Importing the CRUD routes:   updated ./src/Ibw/JobeetBundle/Resources/config/routing.yml


[ERROR] The bundle's "Resources/config/routing.yml" file cannot be imported
from "app/config/routing.yml" because the "IbwJobeetBundle" bundle is
already imported. Make sure you are not using two different
configuration/routing formats in the same bundle because it won't work.
OK

                                         
  Everything is OK! Now get to work :).
```

src/Ibw/JobeetBundle/Resources/config/routing.ymlを修正する。

```
src/Ibw/JobeetBundle/Resources/config/routing.yml

IbwJobeetBundle_job:
    resource: "@IbwJobeetBundle/Resources/config/routing/job.yml"
    prefix:   /job
...
```

ジョブ編集フォームからドロップダウンでカテゴリを編集するため、 Category クラスに _toString() メソッドを追加する。

```
src/Ibw/JobeetBundle/Entity/Category.php

// ...

public function __toString()
{
    return $this->getName() ? $this->getName() : "";
}

// ...
```

キャッシュクリアを行う。

```
$ php app/console cache:clear --env=dev

 // Clearing the cache for the dev environment with debug true                                                          

                                                                                                                        
 [OK] Cache for the "dev" environment (debug=true) was successfully cleared.                                            
                                                                                                                        

Takaharu-no-MacBook-Pro:jobeet takaharukano$ php app/console cache:clear --env=prod

 // Clearing the cache for the prod environment with debug false                                                        

                                                                                                                        
 [OK] Cache for the "prod" environment (debug=false) was successfully cleared.  
```

サーバーを立ち上げて、`http://127.0.0.1:8000/job/`にアクセスすると見た目がずれてるけど、一応表示される。

![スクリーンショット 2017-06-01 13.56.57.png](https://qiita-image-store.s3.amazonaws.com/0/167850/e290d5f0-1f68-33bb-b1c3-49b07c418586.png)