17 |
laravelによるスキャフォールディング (2) |
Posts Tagged with "Design"
既に発行済みのブログであっても適宜修正・追加することがあります。We may make changes and additions to blogs already published.
16 |
laravelによるスキャフォールディング |
imfyOm labsのジェネレータによるスキャフォールディング
Laravelは困りものです。標準のスキャフォールディングが存在しないようです。またLaravel自体の版数も頻繁に上がるたびに完全互換性は無いため、しばしば動作しなくなります。そのため、Laravelによるスキャフォールディングはかなり苦労しました。
最終的にうまくいった、imfyOm labsが開発したlaravel generatorによるスキャフォールディングを紹介します。
ghがインストールされていなければ、以下によりインストールします。太字が入力部分です。
$ sudo dnf install gh
次にgithubトークンが必要なため、githubにログインして、Settings->Developer settings->Personal access tokens->Tokens (classic)により、トークンを取得します。これを環境変数GH_TOKENにセットして、ghを実行します。
$ export GH_TOKEN='xxxxxxxxxxxxx'
$ gh repo clone InfyOmLabs/adminlte-generator example-app
composerをアップデートして、様々なライブラリをインストールします。
$ cd example-app
$ composer update
データベースアクセス可能なように、.env.exampleを.envにコピーし、mysqlのルートパスワードを修正します。
DB_PASSWORD=mysqlルートパスワード
データベース名laravelを作成します。
$ mysql -u root -pmysqlルートパスワード -e 'create database laravel'
アプリケーションのキーを挿入します。これは無くても動作はしますが、セキュリティ上必要です。
参考:https://qiita.com/yk2220s/items/dcbf54c6d1f33a0cb06f
$ php artisan key:generate
モデル名にCategory(単数形)を設定し、コンソールからテーブル定義を入力します。
$ php artisan infyom:api Category <<EOF1
name string text
required
exit
y
EOF1
モデル名にDoc(単数形)を設定し、コンソールからテーブル定義を入力します。
$ php artisan infyom:api Doc <<EOF2
title string text
required|max:512
pages integer text
required|numeric
link string text
required
category_id bigInteger:unsigned:foreign,categories,id select
required|numeric
exit
y
EOF2
マイグレーションを行い、データベースを作成します。laravel固有のメンバが必要なので、既存のデータベースからモデルを作成するよりもこの方法を推奨します。
$ php artisan migrate
これによりmysqlのlaravelデータベースの下にdocsテーブルとcategoriesテーブルが作成されます。テーブルの命名規則は複数形と定まっています。
作成したテーブルからモデルを作成します。
$ php artisan infyom:scaffold Category --fromTable --tableName=categories <<EOF3
y
EOF3
$ php artisan infyom:scaffold Doc --fromTable --tableName=docs <<EOF4
y
EOF4
ルーティング制御であるroutes/web.phpに対してモデルへのルーティングが、以下のように追加されます。
Route::resource('docs', AppHttpControllersDocController::class);
Route::resource('categories', AppHttpControllersCategoryController::class);
ディレクトリの書き込み許可を出します。
$ chmod 777 storage/logs/
chmod 777 storage/framework/sessions/
chmod 777 storage/framework/views/
chmod 777 storage/framework/cache/data/
http://localhost/publicをアクセスし、右上のRegisterからユーザ登録を行います。
15 |
yii2によるスキャフォールディング (4) |
editアクションのビューの修正
続いて鉛筆マークのクリックで表示されるビューである_form.phpを修正します。これはcreateアクションのビューも兼用しています。まず標準の実行結果は図551.1のとおりです。
同じく_form.phpを修正します。自動生成されたコードを見ると、
<?= $form->field($model, 'category_id')->textInput() ?>
となっています。このcategory_idを、同様に(リレーション名).(メンバ名)としてみましたが、そう単純には行きませんでした。
単に表示を変えるのではなく、リストから選択する必要があるためです。そのためdropDownListウィジェットを用います。dropDownListが連想配列を必要とするので、categoryモデルが必要ですが、まず必要なモデルやヘルパーライブラリの使用を宣言します。
use yii\helpers\ArrayHelper;
use app\models\Category;
categoryモデルを全て配列に入れたあと、arrayHelperという便利な配列操作関数のうちのmap関数を用いて、dropDownListに必要な連想配列を作成します。
<?= $form->field($model, 'category_id')->dropDownList(ArrayHelper::map(Category::find()->asArray()->all(), 'id', 'name')) ?>
これを実行した結果を図551.2に示します。
これでyii2のビューの修正は全て完了です。
14 |
yii2によるスキャフォールディング (3) |
アクションviewのビューの修正
続いて目玉アイコンをクリックした時のビューであるview.phpを修正します。実行結果は図550.1のとおりです。
以下にview.phpのDtailViewの修正法を示します。自動生成されたコードを見ると、
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
'title',
'pages',
'link',
'category_id',
],
]) ?>
同様に修正します。
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
'title',
'pages',
'link',
'category.name',
],
]) ?>
これを実行した結果を図550.2に示します。
11 |
yii2によるスキャフォールディング (2) |
アクションindexのビューの修正
index.php/?r=docsとしてドキュメント一覧表を表示します。表549.1に示すように、index.phpにより実行されます。
yii2も標準ではリレーション先まで見てくれないため、手修正を行います。前稿のように、views/docs/index.phpの修正法を示します。自動生成されたindex.phpを見ると、
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yiigridSerialColumn'],
'id',
'title',
'pages',
'link',
'category_id',
これをyii2のGridViewのcolumnsにおいて、(リレーション名).(メンバ名)でリレーション先を表示できるとあるように修正します。
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yiigridSerialColumn'],
'id',
'title',
'pages',
'link',
'category.name',
これを実行した結果を図549.2に示します。数字ではなく、カテゴリ名が表示されています。
タイトル行がNameですが、Categoryに変更したい場合は、’category.name:text:Category'のように修正します。
9 |
yii2によるスキャフォールディング |
yii2によるスキャフォールディング
次にyii2でも同様な作業を行います。yii2のインストール法はcomposerを用います。yii2決定版ガイドのyiiインストール法にあるとおり、以下のコマンドによりbasic applicationを作成します。アプリ名をここではdoctest21としました。同じく太字が入力部分です。
$ composer create-project --prefer-dist yiisoft/yii2-app-basic doctest21
yiiと同様に、適宜config/web.php及びconfig/db.phpを修正して、アプリURI/?r=giiを実行し、giiによりモデルとCRUDを生成します。
まず、giiを有効化します。修正するファイルは、config/web.phpです。
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yiigiiModule',
// uncomment the following to add your IP if you are not connecting from localhost.
'allowedIPs' => ['127.0.0.1'],
];
次にconfig/db.phpを修正し、mysqlを使用することを宣言します。
return [
'class' => 'yiidbConnection',
'dsn' => 'mysql:host=localhost;dbname=test1',
'username' => 'root',
'password' => 'XXXXXXXX',
'charset' => 'utf8',
アクションとビューの対応表
表548.1に画面、コントローラ中のアクション、ビューの対応表を示します。これに従い、それぞれのアクション及びビューを修正します。コントローラはcontrollers/DocsController.phpであり、docs関連ビューは全て、views/docs/の下にあります。
アイコン | コントローラ内 メソッド(アクション) |
1次ビューファイル (黄色がアクションに対応) |
2次ビューファイル |
---|---|---|---|
一覧表示 | actionIndex() | index.php | 無し |
actionCreate() | create.php | _form.php | |
actionView() | view.php | 無し | |
actionUpdate() | update.php | _form.php |
8 |
yii-giiによるスキャフォールディングの修正法 |
giiにより生成されたコードの修正法
元に戻って、標準のgiiにより生成されるコードの追加の修正法を示します。前稿までにCListViewの修正を示しましたが、ここではもう一つのCGridViewの修正を行います。
標準のgiiではテーブル表示にCListViewとCGridViewの2種類を選択するとができます。見かけが良いのはCGridViewで、図547.1のようにエクセルライクな表を作成してくれます。
views/docs/index.phpの修正法を示します。自動生成されたindex.phpを見ると、
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'docs-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'title',
'pages',
'link',
'category_id',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
のように変数ではなくラベルになっています。従って\$model->(リレーション名)->(メンバ名)のように手修正することができないと思っていました。ところがyii2のGridViewのcolumnsにおいて、(リレーション名).(メンバ名)でリレーション先を表示できるとあったため、yiiで実行してみたところ、正常に表示されることが分かりました。この機能はマニュアルに書かれてないようです。
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'docs-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'title',
'pages',
'link',
'category.name',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
これを実行した結果を図547.2に示します。
図547.1ではCategoryのタイトルで数字となっていたカラムが、Nameのタイトルでカテゴリ名に変化しています。ちなみにこのカラムタイトルは、"attribute:format:label"のようにラベルとして指定可能です。例えば元のままの"Category"としたければ、
'category.name:text:Category',
のように記述します。
yiiにおいてはgiixを使えばリレーションに関する手修正は必要ないため、ここまでとします。
7 |
yii-giixによるスキャフォールディング (2) |
giixの実行
新規に追加されたGiixModel GeneratorとGiixCrud Generatorのうち、まずモデルジェネレータでデータベーステーブルに対応するdocs及びcategoryの2つのモデルを作成します。モデル指定では'*'が可能であり、全てのモデルを一度に作成できます。
次に、CRUDジェネレータで今作成した2つのモデルを個々に指定し、それぞれに対してコントローラ及び関連ビューを作成します。
try it(/?r=docs)をクリックしdocsを表示します。
Create表示
次にcreate docsをクリックすると、docsのレコード入力画面になりますが、標準のgiiではcategory_idは数値を入力しなければなりませんでした。ところが、giixでは、次のようにリレーション先のメンバのドロップダウンリストの選択画面を生成してくれます。
giixの秀逸なところは、これまでのように手修正することなしに、リレーションをたどってくれるところです。番号で入力することなく、別の配列のメンバを直接指定することができます。
また、別の表に分けないとcategory nameをひとつひとつテキスト入力する必要がありますが、分離してリレーションを張り、フォーリンキー制約を解釈できるgiixの機能により、ドロップダウンで選択するのみで良くなりました。giixを用いればCRUDの全てにおいて外部制約が自動的に解釈され、数字にはなりません。
リレーションに関してはgiixでは全く修正が不要です。
4 |
yii-giixによるスキャフォールディング |
giixの準備
標準では前稿のようにマニュアル修正が必要でした。これを自動で行うgiixという拡張があります。 yii extensionsからダウンロードし、以下のようにprotected/config/main.phpを設定します。
importにgiixを設定します。
'import'=>array(
:
'ext.giix.components.*', // giix components
:
),
次にmodulesのgiiのうち、generatorPathsをgiixを使用するように設定します。
'modules'=>array(
:
'gii'=>array(
'class'=>'system.gii.GiiModule',
'ipFilters'=>array('127.0.0.1'),
'generatorPaths' => array(
'ext.giix.generators', // giix generators
),
),
ブラウザでアプリケーションにアクセスし、/?r=giiとしてgiixを起動します(r=giixではない)。
新規にGiixModel GeneratorとGiixCrud Generatorが追加されています。
3 |
yii-giiによるスキャフォールディング |
giiの実行
ブラウザでアプリケーションにアクセスし、/?r=giiとしてgiiを起動します。パスワードを適宜入力します。IPアドレスが許可されていれば、図544.1の画面が現れます。様々なジェネレータが用意されています。
まず、モデルジェネレータでデータベーステーブルに対応するdocs及びcategoryの2つのモデルを作成します。
次に、CRUDジェネレータで今作成した2つのモデルを指定し、それぞれに対してコントローラ及び関連ビューを作成します。
try it(/?r=category)をクリックしcategoryを表示します。
リレーションの構造
docsテーブルの中のカテゴリ種別は別のテーブルcateogryのidを示しています。これをforeign keyとして以下のようにリレーションが張られています。protected/models/Docs.php(一部)は以下のようになっています。
public function relations()
{
return array(
'category' => array(self::BELONGS_TO, 'Category', 'category_id'),
);
}
Docモデル中のリレーションcategoryは、"Docs belong to a Category"と読みます。n対1の関係を示します。
protected/models/Category.php(一部)は以下のようになっています。
public function relations()
{
return array(<br />
'docs' => array(self::HAS_MANY, 'Docs', 'category_id'),
);
}
Categoryモデル中のリレーションdocsは、"A Category has many docs"と読みます。1対nの関係を示します。
表示の修正
データベース内容一覧を表示するためのviews/docs/_view.phpを見ると、自動生成後は
<b><?php echo CHtml::encode($data->getAttributeLabel('category_id')); ?>:</b>
<?php echo CHtml::encode($data->category_id); ?>
となっており、図544.3のようにcategory_idとして数字が表示されます。
<b><?php echo CHtml::encode($data->getAttributeLabel('category_id')); ?>:</b>
<?php echo CHtml::encode($data->category->name); ?>
これを表示すると図544.4のようにカテゴリ名で表示されます。
これがYiiの素晴らしい機能で、$data->(リレーション名)->(参照メンバ)のように、リレーションをあたかも構造体のように辿ることができます。自動的にリレーション先の表のメンバを参照可能です。
ページ: