phalcon あれやこれや2 phalcon
コントローラから もでるつかって sql実行
TestController.php
public function test()
{
$region = Regions::findFirst(1);
$prefectures = $region->prefectures;
}
PhalconでJOINを使いたい時にはModelのinitialize()内で、hasOne hasMany belongsToなどを使います。
model/Prefectures.php
public function initialize()
{
// 地方を親に持つのでbelongsTo
$this->belongsTo( region_id Regions id );
// 子に市区町村を持つのでhasMany
$this->hasMany( id Towns prefecture_id );
// 都道府県の詳細は1対1なのでhasOne
$this->hasOne( id PrefectureDetails prefecture_id );
}
Phalconでは、リレーションはモデルのinitialize()メソッドの中で定義する必要があります。
リレーションを定義するメソッドには4種類あり、
★★いずれも「自分自身のフィールド名(≒カラム名)」「参照するモデル名」「参照するフィールド名」の3つのパラメータをとります。
------------------------------------
メソッド 状態
hasMany 1対多
hasOne 1対1
belongsTo 多対1
hasManyToNany 多対多
------------------------------------
以下のようなテーブルの関係を考えてみます。
CREATE TABLE `robots` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT
`name` varchar(70) NOT NULL
`type` varchar(32) NOT NULL
`year` int(11) NOT NULL
PRIMARY KEY (`id`)
);
CREATE TABLE `robots_parts` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT
`robots_id` int(10) NOT NULL
`parts_id` int(10) NOT NULL
`created_at` DATE NOT NULL
PRIMARY KEY (`id`)
KEY `robots_id` (`robots_id`)
KEY `parts_id` (`parts_id`)
);
CREATE TABLE `parts` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT
`name` varchar(70) NOT NULL
PRIMARY KEY (`id`)
);
1つのRobotsは、1つ以上のRobotsPartsをもつ
1つのPartsは、1つ以上のRobotsPartsをもつ
1つ以上のRobotsPartsが、Robotsに属する
1つ以上のRobotsPartsが、Partsに属する
RobotsとPartsは、RobotsPartsを介して、多対多の関係になっている(RobotsPartsは中間テーブル)
ER:robots-robots_parts-parts
それぞれのモデルは以下のように実装できます(Phalcon DevToolsはv1.3.1現在、リレーションの自動生成には対応していません。リレーションの記述は手動で行う必要があります)。
<?php
class Robots extends ¥Phalcon¥Mvc¥Model
{
public $id;
public $name;
public function initialize()
{
$this->hasMany( id RobotsParts robots_id );
}
}
<?php
class Parts extends ¥Phalcon¥Mvc¥Model
{
public $id;
public $name;
public function initialize()
{
$this->hasMany( id RobotsParts parts_id );
}
}
<?php
class RobotsParts extends ¥Phalcon¥Mvc¥Model
{
public $id;
public $robots_id;
public $parts_id;
public function initialize()
{
$this->belongsTo( robots_id Robots id );
$this->belongsTo( parts_id Parts id );
}
}
リレーション定義メソッドの第1引数には、
★★自分自身のフィールド名、第2引数には参照するモデル名、第3引数には参照するモデルのフィールド名を渡します。
複数のフィールドのリレーションを指定したい場合、配列を使うこともできます。
3つのモデルからなる多対多の関係を単一のメソッドで記述すると、以下のようになります。
<?php
class Robots extends ¥Phalcon¥Mvc¥Model
{
public $id;
public $name;
public function initialize()
{
$this->hasManyToMany(
id
RobotsParts
robots_id parts_id
Parts
id
);
}
}
リレーションを活用する
モデルの関係が明示的に定義されると、関連するレコードを簡単に一括取得できます。
<?php
$robot = Robots::findFirst(2);
foreach ($robot->robotsParts as $robotPart) {
echo $robotPart->parts->name ¥n ;
}
Phalconは、関連するモデルへのデータの保存・取得にマジックメソッド(__set/__get/__call)を用います。
リレーションと同じ名前のプロパティにアクセスすると、関連するレコードが自動で取得されます。
<?php
$robot = Robots::findFirst();
$robotsParts = $robot->robotsParts; // RobotsPartsの関連レコード
getterもマジックメソッドで実装されています(明示的な定義が不要なgetter:マジックゲッター)。
<?php
$robot = Robots::findFirst();
$robotsParts = $robot->getRobotsParts(); // RobotsPartsの関連レコード
$robotsParts = $robot->getRobotsParts(array( limit => 5)); // パラメータを渡す
★★Phalcon¥Mvc¥Modelは、「get」が頭についているメソッドの呼び出しがされると、
findFirst()又はfind()の結果を返します。以下の例では、マジックゲッターを使った場合と使わない場合とを比較しています。