CakePHPでRails Tutorialをやってみる〜その2 ほぼ静的なページの作成〜
はじめに
業務でCakePHPを使用することになったので、勉強を始めました。
本を買おうかとも思ったのですが、折角なのでRails TutorialをCakePHPで書き換えながら勉強をしようかと思いました。
自分の整理と、他の方たちへの参考になればと思い、記事にさせていただきます。
とばせる部分はとばしているので、全て実施するわけではありません。
コントローラーの生成
CakePHPにはbake
コマンドという、ファイルを生成してくれるコマンドがあります。
Cake(ケーキ)をbake(焼く)というのはなかなか洒落ているのではないかと思っています。
Bakeでコード生成
今回はコントローラーだけ生成したいと思います。
StaticPagesController
という名前にします。
一緒にテストコードも生成してくれます。
$ php bin/cake.php bake controller StaticPages
Creating file /home/ubuntu/workspace/cakephp_de_rails_tutorial/src/Controller/StaticPagesController.php
Wrote `/home/ubuntu/workspace/cakephp_de_rails_tutorial/src/Controller/StaticPagesController.php`
生成されたコントローラーにはRESTなindex
のようなメソッドが記載されているので、これを消して必要なものを追記していきます。
今回、StaticPages
にはhome
、help
、about
、contact
を追加します。
<?php
namespace App\Controller;
use App\Controller\AppController;
/**
* StaticPages Controller
*
*
* @method \App\Model\Entity\StaticPage[] paginate($object = null, array $settings = [])
*/
class StaticPagesController extends AppController
{
public function home()
{
}
public function help()
{
}
public function about()
{
}
public function contact()
{
}
}
ルーティングの設定
URLからコントローラーのアクションを紐づけるルーティングを設定します。
ファイルはconfig/routes.php
です。
ルーティング
ルートパスと各メソッドの設定をします。
Router::scope('/', function (RouteBuilder $routes) {
/**
* Here, we are connecting '/' (base path) to a controller called 'Pages',
* its action called 'display', and we pass a param to select the view file
* to use (in this case, src/Template/Pages/home.ctp)...
*/
- $routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
+ $routes->connect('/', ['controller' => 'StaticPages', 'action' => 'home']);
/**
* ...and connect the rest of 'Pages' controller's URLs.
*/
+ $routes->connect('/home', ['controller' => 'StaticPages', 'action' => 'home']);
+ $routes->connect('/help', ['controller' => 'StaticPages', 'action' => 'help']);
+ $routes->connect('/about', ['controller' => 'StaticPages', 'action' => 'about']);
+ $routes->connect('/contact', ['controller' => 'StaticPages', 'action' => 'contact']);
テンプレートの作成
それぞれのテンプレートを作成します。
とりあえずのテストなので何でも良いかと思いますが、Rails Tutorialのものをそのまま使用しようと思います。
(Railsではないのにリンクができてしまっていますが。。。)
なお、各ファイルはsrc/Template
の下にStaticPages
というディレクトリを作成し、その中で作っていきます。
<h1>Sample App</h1>
<p>
This is the home page for the
<a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
sample application.
</p>
<h1>Help</h1>
<p>
Get help on the Ruby on Rails Tutorial at the
<a href="https://railstutorial.jp/help">Rails Tutorial help page</a>.
To get help on this sample app, see the
<a href="https://railstutorial.jp/#ebook"><em>Ruby on Rails Tutorial</em>
book</a>.
</p>
<h1>About</h1>
<p>
<a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
is a <a href="https://railstutorial.jp/#ebook">book</a> and
<a href="https://railstutorial.jp/#screencast">screencast</a>
to teach web development with
<a href="http://rubyonrails.org/">Ruby on Rails</a>.
This is the sample application for the tutorial.
</p>
<h1>Contact</h1>
<p>
Contact the Ruby on Rails Tutorial about the sample app at the
<a href="https://railstutorial.jp/contact">contact page</a>.
</p>
表示確認
サーバーを起動して動作を確認します。
$ bin/cake server -H $IP -p $PORT
下図のようになっていれば問題ないと思います。
PHPUnitでテストコードを書く
PHPUnitのインストール
ここまでのテストコードを書いてみたいと思います。
CakePHPではPHPUnitがサポートされているようなので、そちらを使用します。
テスト
プロジェクトディレクトリのcomposer.json
を編集します。
suggest
の中にあるphpunit
と、ついでにcakephp-codesniffer
をrequire-dev
に移します。
cakephp-codesniffer
は、コーディング規約に沿っているか確認してくれるものです。
特に記事にはしませんが、開発環境であれば合っても良いのかな、と思います。
(Rubyでいうrubocop
みたいなものですかね。。。)
https://github.com/cakephp/cakephp-codesniffer
"require-dev": {
"psy/psysh": "@stable",
"cakephp/debug_kit": "~3.2",
"cakephp/bake": "~1.1",
+ "phpunit/phpunit": "*",
+ "cakephp/cakephp-codesniffer": "*"
},
"suggest": {
"markstory/asset_compress": "An asset compression plugin which provides file concatenation and a flexible filter system for preprocessing and minification.",
"dereuromark/cakephp-ide-helper": "After baking your code, this keeps your annotations in sync with the code evolving from there on for maximum IDE and PHPStan compatibility.",
- "phpunit/phpunit": "Allows automated tests to be run without system-wide install.",
- "cakephp/cakephp-codesniffer": "Allows to check the code against the coding standards used in CakePHP."
},
この状態で、Composerをアップデートします。
$ sudo php composer.phar update
これで、phpunit
コマンドが使用できるかと思います。
試しに下記が起動できるか確認します。
(恐らくエラーになるかと思います。)
$ vendor/bin/phpunit
テストコードの作成
先ほどbake
で生成されたStaticPagesControllerTest.php
というファイルがあるので、そちらを修正していきます。
<?php
namespace App\Test\TestCase\Controller;
use App\Controller\StaticPagesController;
use Cake\TestSuite\IntegrationTestCase;
/**
* App\Controller\StaticPagesController Test Case
*/
class StaticPagesControllerTest extends IntegrationTestCase
{
/**
* Test home method
*
* @return void
*/
public function testHome()
{
$this->get('/home');
$this->assertTemplate('StaticPages/home');
}
/**
* Test help method
*
* @return void
*/
public function testHelp()
{
$this->get('/help');
$this->assertTemplate('StaticPages/help');
}
/**
* Test about method
*
* @return void
*/
public function testAbout()
{
$this->get('/about');
$this->assertTemplate('StaticPages/about');
}
/**
* Test contact method
*
* @return void
*/
public function testContact()
{
$this->get('/contact');
$this->assertTemplate('StaticPages/contact');
}
}
基本的に静的なページなので、テストでやっていることは同じです。
-
get
で対象のURLにアクセスする。 - 表示されているテンプレートが正しいか確認する(
assertTemplate
)。
IntegrationTestCase
を継承していると便利なアサーションメソッドを使用できます。
下記のコマンドで対象のファイルだけテストできます。
GREENになればOKです。
$ vendor/bin/phpunit tests/TestCase/Controller/StaticPagesControllerTest.php
また、テスト単位で実行するには、filter
オプションが使用できます。
filter
に一致するテストのみ実行してくれます。
# Homeがつくテストだけ実行
$ vendor/bin/phpunit --filter="/Home/" tests/TestCase/Controller/StaticPagesControllerTest.php
vendor/bin/phpunit
だけ実行すると、全てのテストを実行できます。
ただ、今回の場合、PagesControllerTest.php
が引っかかってしまいます。
そのため、コメントアウトするか、消してしまっても良いと思います。
少し動的なページ
タイトルタグの中身をページごとに変わるようにします。
head
タグなどは、src/Template/Layout/default.ctp
に書かれております。
まずはテストコードを追記してみる
Rails Tutorialのようにテスト駆動開発(TDD)っぽく、まずはテストから修正します。
今回はHome | Ruby on Rails Tutorial Sample Appのような文言がちゃんと含まれているか確認します。
共通文言はライフサイクルコールバックのsetUp
を使用し、テスト前にプロパティにセットします。
<?php
namespace App\Test\TestCase\Controller;
use App\Controller\StaticPagesController;
use Cake\TestSuite\IntegrationTestCase;
class StaticPagesControllerTest extends IntegrationTestCase
{
+ public $base_title;
+ public function setUp()
+ {
+ parent::setUp();
+ $this->base_title = 'Ruby on Rails Tutorial Sample App';
+ }
public function testHome()
{
$this->get('/home');
$this->assertTemplate('StaticPages/home');
+ $this->assertResponseContains("Home | {$this->base_title}");
}
public function testHelp()
{
$this->get('/help');
$this->assertTemplate('StaticPages/help');
+ $this->assertResponseContains("Help | {$this->base_title}");
}
public function testAbout()
{
$this->get('/about');
$this->assertTemplate('StaticPages/about');
+ $this->assertResponseContains("About | {$this->base_title}");
}
public function testContact()
{
$this->get('/contact');
$this->assertTemplate('StaticPages/contact');
+ $this->assertResponseContains("Contact | {$this->base_title}");
}
}
これでテストを実行すると、エラーになります。
テンプレートの修正
コントローラーから値を受け取り、動的にタイトルタグを変更したいと思います。
<title>
- <?= $cakeDescription ?>:
- <?= $this->fetch('title') ?>
+ <?= "{$title} | Ruby on Rails Tutorial Sample App" ?>
</title>
コントローラーの修正
コントローラーからsetメソッドを使用して値を渡します。
<?php
namespace App\Controller;
use App\Controller\AppController;
class StaticPagesController extends AppController
{
public function home()
{
+ $this->set('title', 'Home');
}
public function help()
{
+ $this->set('title', 'Help');
}
public function about()
{
+ $this->set('title', 'About');
}
public function contact()
{
+ $this->set('title', 'Contact');
}
}
これでテストが通ったかと思います。
さいごに
色々端折ってしまいましたが、第3章をやってみました。
PHPUnitはRubyのminitestに近い感じで使えそうです。
次回は第4章をとばして、5章をやりたいと思います。
次回:その3 レイアウトの作成
Author And Source
この問題について(CakePHPでRails Tutorialをやってみる〜その2 ほぼ静的なページの作成〜), 我々は、より多くの情報をここで見つけました https://qiita.com/naoki85/items/0b7e7ea106a1c661ed35著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .