CakePHP

CakePHP2.1のモデルクラスの概要

更新日:

今日は、CakePHP2.1のモデルクラスの概要について調べてみたいと思います。CakePHPは、命名規則に則ってデータベーステーブルを作成していれば、モデルは自動的に作成されますので、モデルは明示的に作成しなくても大丈夫です。つまり、モデルの最低限の機能(データの入出力)しか使わないのなら、app/Modelにモデルを作成する必要が無いということです。

モデルがらみの命名規則

1. まず最初にモデルがらみの命名規則から調べてみましょう。テーブル名をmy_collectionsとして作成することにします。

  • テーブル名(my_collections)
    先頭小文字の複数形アンダースコア記法(単語が2つ以上重なる場合は、アンダースコア『_』で単語間を繋ぎ、最後の単語は必ず複数形にします)。
  • モデル名(MyCollection)
    先頭大文字の単数形キャメル記法(単語が2つ以上重なる場合はそれぞれの単語の先頭文字を大文字にして、残りの文字は小文字で作成します。尚、テーブル名で使用したアンダースコアは使用しません)。
  • モデルクラス名(MyCollection)
    先頭大文字の単数形キャメル記法(モデル名とモデルクラス名は全く同じです)。
  • モデルファイル名(MyCollection.php)
    先頭大文字の単数形キャメル記法(cakePHP1.3迄は、先頭小文字の単数形アンダースコア記法でした。my_collection.php)。

    app/Model/MyCollection.php

    <?php
     class MyCollection extends AppModel{
     //ここにアソシエーションやバリデーションを記述
     }
     ?>
  • コントローラ名(MyCollections)
    先頭大文字複数形のキャメル記法
  • コントローラクラス名(MyCollectionsController)
    先頭大文字複数形のキャメル記法+Controller (Cake1.3迄は、先頭小文字複数形のアンダースコア法でした。my_collections_controoler)。
  • コントローラファイル名(MyCollectionsController.php)
    先頭大文字複数形のキャメル記法+Controller(同じくCake1.3迄は、先頭小文字複数形のアンダースコア記法でした。my_collections_controller.php)。

    app/Controller/MyCollectionsController.php

    <?php
     class MyCollectionController extends AppController{
     //ここにコードを記述
     }

2. 今回、モデルの命名規則とコントローラの命名規則を調べ直したら、コントローラは複数形であることに気がつきました。単数形でも普通に動いていたので、あまり気にしていなかったのですが、やはり設定よりも規約を重視するCakePHPですので、命名規則は守った方がいいと思います。今後気をつけたいと思います。尚、これに伴いビューのフォルダ(ディレクトリ)名も複数形にする必要があります。

3. 次に、データベーステーブルのフィールド名についても調べてみました。これも命名規則に則って作成しておけば、アソシエーションの設定が簡単になります。

4. まず、主キー名は小文字のidとします。フィールド名は小文字の単数形アンダースコア記法にします。

5. 外部キーは、参照元のテーブル名の単数形+『_id』とします。つまり、参照元がcollection_imagesテーブルなら、外部キーはcollection_image_idとなります(imagesが単数形のimageになります)。

6. 命名規則に則らなければデータベーステーブルを利用できないということでは無いのですが、モデルの記述が簡単になりますし、間違いも少なくなります。古いデータベーステーブルを扱うのにいちいち命名規則に則って書き換えるのは非効率ですが、新しくデータベーステーブルを作成するのであれば、CakePHPの命名規則に則った方がいいと思います。

モデルの基本的な仕組み

7. CakePHPのモデルは、基本的に3つの仕組みからなっています。1つは、データの入出力を行うための仕組みです。これが、一番の基本になっています。

8. 2つめがデータが安全に入出力できるための検証機能、つまりバリデーションです。実際にデータベースに入出力を行う前や、取り出した値をチェックし、整合性を確かめるための仕組みです。

9. 3つめがデータ同士の関連性を具体化するための仕組みであるアソシエーションです。CakePHPのアソシエーションは、実際にSQLで記述すると面倒なJOIN機能を簡単に操作できるようにしたとっても便利な仕組みです。尚、アソシエーションに関しては、以前、『Cake2.1でフォームリストの作成(実践編その7)』でご紹介していますので、参照して下さい。

10. それでは、これらの3つの基本的な仕組みを頭に入れながら、Modelクラスのメソッドを1つずつ調べていきたいと思います。

Modelクラスのメソッド

11.  まず、今回は、モデル名をCollectionとして、メソッドの例題を記述しますので、$this->Collection->find()と記述している場合は、Collecitonモデル(データベースのテーブル名がcollections、コントローラは、CollectionsController.php)を指していますので、それぞれのモデルに置き換えて下さい。

  • find(検索タイプ,オプション配列)
    データベーステーブルから検索を行い、レコードを入手します。最も使用頻度の高い、基本的なメソッドです。 これは、以前、『CakePHP2.1のfindメソッド』でご紹介していますので、省略します。
  • findBy(指定フィールドの検索条件値)
    findByは、モデル内に定義されているマジックメソッドです。findBy以降にキャメル形式のフィールド名を付加することで、そのフィールドを検索条件にしたデータを取得することが出来ます。例えばidを条件とした検索を行いたいときは『findById()』とします。検索した値が配列として戻ります。

app/Controller/CollectionsController.php

public function sample(){
 $findby=$this->Collection->findById(1);
 //上記と下記は結果は同じです
 $find=$this->Collection->find('first',array(
 'condition'=>array('id'=>1),
 )); 
 //ビューに値を渡す
 $this->set('findby',$findby);
 $this->set('find',$find);
 }

app/View/Collections/sample.ctp

<h1>Sampleプログラム</h1>
 <table cellpadding="0" cellspacing="0">
 <tr>
 <th><?php echo "ID";?></th>
 <th><?php echo "タイトル";?></th>
 <th><?php echo "作成日";?></th>
 <th><?php echo "コード番号";?></th>
 <th><?php echo "保管場所";?></th>
 </tr>
 <tr>
 <td><?php echo h($findby['Collection']['id']); ?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['title']);?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['created']); ?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['col_code']); ?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['save_space']); ?>&nbsp;</td>
 </tr>
 <tr>
 <td><?php echo h($find['Collection']['id']); ?>&nbsp;</td>
 <td><?php echo h($find['Collection']['title']);?>&nbsp;</td>
 <td><?php echo h($find['Collection']['created']); ?>&nbsp;</td>
 <td><?php echo h($find['Collection']['col_code']); ?>&nbsp;</td>
 <td><?php echo h($find['Collection']['save_space']); ?>&nbsp;</td>
 </tr>
 </table>

  • bindModel(アソシエーションの連想配列,$reset)
    通常アソシエーションは、モデル内のプロパティに定義して使用しますが、このメソッドを使用することにより動的にアソシエーションを定義することが出来ます。第2引数の値をtrueにセットすると一時的な変更となり、find()等を行うとリセットされます。ずっと変更したい場合はfalseにセットします。デフォルトはtrueです。

app/Controoler/CollectionsController.php

public function sample(){
 $this->Collection->bindModel(array(
 'hasOne'=>array(
 //アソシエーション名を作成
 'ColBind'=>array(
//モデルクラス名をセット
 'className'=>'ColImage',
//外部キーをセット
 'foreignKey'=>'collection_id',
 ),
 ),
 ));
 $findby=$this->Collection->findById(144);
 $this->set('findby',$findby);
 }

app/View/Collections/sample.ctp

<h1>Sampleプログラム</h1>
 <table cellpadding="0" cellspacing="0">
 <tr>
 <th><?php echo "ID";?></th>
 <th><?php echo "タイトル";?></th>
 <th><?php echo "作成日";?></th>
 <th><?php echo "コード番号";?></th>
 <th><?php echo "保管場所";?></th>
 </tr>
 <tr>
 <td><?php echo h($findby['Collection']['id']); ?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['title']);?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['created']); ?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['col_code']); ?>&nbsp;</td>
 <td><?php echo h($findby['ColBind']['filename']); ?>&nbsp;</td>
 </tr>
 </table>

  • unbindModel(アソシエーションの連想配列,$reset)
    現在モデル内に設定されているアソシエーションから、指定モデルについての結合を解除します。$resetをtureに設定すると、一時的な変更になり、find()等を行うとリセットされます。ずっと変更したい場合はfalseを指定します。デフォルトはtrueです。
  • setSource(テーブル名)
    このメソッドは、モデルに対して使用したいテーブルを指定して利用できるようにセッティングを行います。このメソッドを利用することで、後からテーブルを変更することが出来ます。

app/Controller/CollectionsController.php

public function sample(){
 //指定したテーブルでモデルのセッティング
 $this->Collection->setSource('members');
 $findby=$this->Collection->findById(1);
 $this->set('findby',$findby);
 }

app/View/Collections/sample.ctp

<h1>Sampleプログラム</h1>
 <table cellpadding="0" cellspacing="0">
 <tr>
 <th><?php echo "ID";?></th>
 <th><?php echo "氏名";?></th>
 <th><?php echo "パスワード";?></th>
 <th><?php echo "メールアドレス";?></th>
 </tr>
 <tr>
 <td><?php echo h($findby['Collection']['ID']); ?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['mm_name']);?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['mm_passw']); ?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['mm_mail']); ?>&nbsp;</td>
 </tr>
 </table>

  • set(フィールド名,値)
    このメソッドは、モデルや書き出しやバリデートに必要なデータを明示的にセットします。又、第1引数にフィールド名をキーとする連想配列を指定することで、複数フィールドの値をセットすることが出来ます。

 app/Controller/CollectionsController.php

public function sample(){
 //モデルに値をセットする
 $this->Collection->set('title','愛と誠');
 $this->Collection->save();
 $findby=$this->Collection->find('first',array(
 'order'=>array('modified'=>'desc')));
 $this->set('findby',$findby);
 }

app/View/Collections/sample.ctp

<h1>Sampleプログラム</h1>
 <table cellpadding="0" cellspacing="0">
 <tr>
 <th><?php echo "ID";?></th>
 <th><?php echo "タイトル";?></th>
 <th><?php echo "作成日";?></th>
 <th><?php echo "更新日";?></th>
 </tr>
 <tr>
 <td><?php echo h($findby['Collection']['id']); ?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['title']);?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['created']); ?>&nbsp;</td>
 <td><?php echo h($findby['Collection']['modified']); ?>&nbsp;</td>
 </tr>
 </table>

  • deconstruct(フィールド名,日時データ)
    指定したフィールドで認識できる日時形式に、指定した日時データを加工します。
  • schema(フィールド名)
    指定フィールドのスキーマ(データベース構造)を入手します。フィールド名を指定しなければ、モデル内で扱う全てのフィールドに対してスキーマを取得します。
  • getColumnType(カラム名)
    指定カラム(フィールド)のデータ形式を取得します。
  • getColumnTypes()
    モデル内の全てカラム(フィールド)のデータをカラム名をキーとした連想配列で取得します。
  • hasField(フィールド名,$checkVitual)
    指定したフィールドが存在するかどうかを調べます。第2引数がtrueの場合は、バーチャルフィールド内も調べます。初期値はfalseです。
  • isVirtualField(フィールド名)
    指定フィールドがバーチャルフィールドかどうかを調べます。
  • getVirtualField(バーチャルフィールド名)
    モデル内で定義されているバーチャルフィールドの定義内容を取得します。
  • create(データの配列,変更したいプライマリキー)
    レコードを新しく登録するための初期化を行います。 第2引数のプライマリキーは、基本的にidが使用されますので、記述する必要がありませんが、指定することで任意にキーに変更することが出来ます。
  • read(フィールドの配列,id)
    指定したプライマリキー(基本的にはid)に対するレコードを取得します。find()と同じような使い方が出来ます。

app/Controller/CollectionsController.php

public function sample(){
 //モデルに値をセットする
 $result=$this->Collection->read(array(),1);
 $this->set('result',$result);
 }

app/View/Collections/sample.ctp

<h1>Sampleプログラム</h1>
 <table cellpadding="0" cellspacing="0">
 <tr>
 <th><?php echo "ID";?></th>
 <th><?php echo "タイトル";?></th>
 <th><?php echo "作成日";?></th>
 <th><?php echo "更新日";?></th>
 </tr>
 <tr>
 <td><?php echo h($result['Collection']['id']); ?>&nbsp;</td>
 <td><?php echo h($result['Collection']['title']);?>&nbsp;</td>
 <td><?php echo h($result['Collection']['created']); ?>&nbsp;</td>
 <td><?php echo h($result['Collection']['modified']); ?>&nbsp;</td>
 </tr>
 </table>

  • field(フィールド名,検索条件,ソート順)
    検索条件を満たすレコードに対するフィールドの値を取得します。第2引数の検索条件が省略された場合、又は、複数のレコードが見つかった場合は最初のレコードの値を取得します。
  • saveField(フィールド名,値,$validate)
    特定のフィールドに対して保存を行います。第3引数がtrueの場合は、保存前にバリデーション処理を行います。初期値はfalseです。保存が成功した場合は、モデル内にその保存値がある場合はその値、無い場合はtrueを返します。保存に失敗した場合はfalseを返します。
  • save(保存値の配列,$validate,保存フィールド名の配列)
    モデルの内容をデータベースに保存します。データベーステーブルへのインサートとアップデートの両方ともこのメソッドを使用します。save()メソッドを実行するときに、プライマリーキーが存在している場合はアップデート、存在していない場合はインサートを行います。
  • saveAll(保存データ,オプション値)
    複数レコードを保存するときにこのメソッドを使用します。
  • updateAll(フィールドの連想配列,更新条件の配列)
    複数のフィールドをまとめて更新します。
  • delete(id,アソシエーション削除の有無)
    該当するレコードを削除します。第2引数は初期値がtrueでアソシエーションの削除されるようになっています。アソシエーションを削除しないときはfalseにします。
  • deleteAll(条件,アソシエーション削除の有無,コールバックの有無)
    条件の合う全てのデータを一括で削除します。。第3引数のコールバックはデフォルトでfalseに指定されていますので、コールバックを実行する場合はtrueに指定します。
  • exists()
    現在のモデルに格納されているレコード値がテーブル内に存在するかどうかを調べます。レコードがあれば、ture、無ければ、falseを返します。
  • hasAny(条件配列)
    指定した条件のレコードの有無を調べます。true又は、falseが返ります。

app/Controller/CollectionsController.php

public function sample(){
 $search='ダヴィンチ';
 //もし指定レコードがあれば
 if($this->Collection->hasAny(array(
 'title like'=>"%$search%",))){
 $result=$search."はあります。";
 //指定レコードが無ければ
 }else{
 $result=$search."はありません。";
 }
 $this->set('result',$result);
 }

app/View/Collections/sample.ctp

<h1>Sampleプログラム</h1>
<?php echo h($result);?>

  • isUnique(フィールドの配列,全てか否か)
    指定フィールドの値が他のレコードに対してユニークかどうかを調べます。第2引数は、 指定フィールドの全てがユニークかどうかを調べます。第2引数は指定フィールドの全てがユニークかどうかを指定します。tureにすると、全てのフィールドがユニークである必要があります。ユニークである場合はtureが返ります。
  • query($sql)
    このメソッドは直接SQLを発行する場合に使用します。
  • validates(オプション)
    現在のモデル内に登録されている内容についてバリデーションを行います。
  • invalidFields(オプション)
    現在のモデル内に定義されているフィールド値に対してバリデーションを行います。
  • getID(リスト)
    現在モデルが保有しているプライマリキーを取得します。引数には、複数のプライマリキーが存在するときのリスト番号を指定します。デフォルトは0で、一番先頭のプライマリキーを取得します。
  • getInsertID()
    save()等を行ってレコードの挿入があった場合に、そのレコードのプライマリキーを取得します。
  • getNumRows()
    直前に実行したfind()等でデータを取得したときの、実際に取得できたレコード数を取得します。find('count')はSQLで取得できるレコード数であるのに対して、このメソッドは、実際に取得したレコード数であるところが若干違います。
  • getAffectedRows()
    このメソッドは、save()によって、更新・挿入のあったレコード数を取得します。
  • getAssociated(アソシエーションタイプ)
    このメソッドは、モデル内に定義されているアソシエーション情報を取得します。 NULL値を指定すると全てのタイプに対して取得します。
  • joinModel(アソシエーションモデル名,外部キーの配列)
    アソシエーションによって結合されたモデルのフィールド名を取得します。

app/Controller/CollectionsController.php

public function sample(){
 $result=$this->Collection->joinModel('ColAssort');
 $this->set('result',$result);
 }

app/View/Collections/sample.ctp

<h1>Sampleプログラム</h1>
<?php echo var_dump($result);?>

  • beforeFind(クエリデータ)
    レコードの検索実行前のコールバックです。検索前に追加処理を行う場合は、このメソッドを上書きします。 このコールバックでは、クエリデータを受け取って事前処理することが出来ます。
  • aftefFind(加工前の結果、複数or1レコード)
    検索後に実行されるコールバックです。 第1引数を加工するのに向いたコールバックです。第2引数をtrueにすると、複数のレコードを取得します。falseにすると、1レコードに対するフィールド値を連想配列で取得します。初期値はfalseです。
  • beforeSave(オプション)
    保存前に実行されるコールバックです。戻り値がfalseの場合は保存処理が停止します。
  • afterSave(新規保存か否か)
    保存後に実行されるコールバックです。レコードが既に追加されている場合はtrue、新規の場合はfalseを指定します。
  • beforeDelete(アソシエーション削除の有無)
    レコードの削除前に実行されるコールバックです。アソシエーションも作事する場合はtrueを指定します。
  • aftefDelete()
    レコードの削除後に実行されるコールバックです。
  • beforeValidate(オプション)
    バリデーションが行われる前に実行されるコールバックです。成功時はtrue、エラー時はfalseが返ります。
  • onError()
    モデル内でエラーが発生した場合時実行されるコールバックです。

本日は以上です。

-CakePHP
-

Copyright© WinRoad徒然草 , 2018 All Rights Reserved Powered by AFFINGER5.