Yiiで複数のテーブルからデータを取り出す方法

select o.id, o.name, i.id, i.quantity from order as o
left join item as i on o.id=i.order_id
where o.created>'2012-12-12'
and i.status=1;

のように複数のテーブルからデータを取得する方法です。

まずすることは、orderとitemテーブル用にOrderモデルとItemモデルを作成します。

次に、Orderモデルで

public function relations()
{
  return array(
    'items' => array(self::HAS_MANY, 'Item', 'order_id'),
  );
}

のようにrelationsの設定を行います。
この場合、orderとitemは一対多の関係にあるということを示しています。
※relationsの設定については公式ガイドに詳しく載っています。

Orderモデル内で、findAllを使ってデータを取得する場合は、

$criteria = new CDbCriteria;
$criteria->select='t.id, t.name, items.id, items.quantity';
$criteria->compare('t.created','>2012-12-12');
$criteria->compare('items.status','1');

$datas=$this->with(array('items'))->findAll($criteria);

のようにすればよいです。
また、CActiveDataProvider経由でデータを取得する場合、

$criteria = new CDbCriteria;
$criteria->select='t.id, t.name, items.id, items.quantity';
$criteria->compare('t.created','>2012-12-12');
$criteria->mergeWith(array(
  'with' => array(
    'items'=>array(
      'condition'=>'items.status=:status',
      'params'=>array(
        ':status'=>1
      ),
    ),
  ),
  'together'=>true));

$dataProvider =new CActiveDataProvider(get_class($this), array(
  'criteria' => $criteria,
));

のようにする必要があります。
ちなみに、GridViewなどでデータを表示する場合は以下のようにします。

<?php $this->widget('bootstrap.widgets.TbGridView',array(
  'id'=>'order-grid',
  'dataProvider'=>$dataProvider,
  'columns'=>array(
    'id',
    'name',
    array(
      'name'=>'items.id',
      'value'=>'$data->items[0]->quantity'
    ),
    array(
      'name'=>'items.quantity',
      'value'=>'$data->items[0]->quantity'
    ),
  ),
));?>

※注意
relationsでHAS_MANYを使っている場合、「$data->items[0]->quantity」のようにitemsのところが配列になります。
HAS_ONEの場合なら「$data->items->quantity」となります。

投稿日:
カテゴリー: php タグ: