はじめての CakePHP のアソシエーションで店舗データを取り出す時に複数の商品データも同時に取得する $hasMany の使い方

以前 $belongsTo で商品データを取り出す時に店舗データも同時に取得する方法について書きました。今回は逆に、店舗データを取り出す際に紐付く商品データも一緒に取り出す方法について書いていきます。本記事を書くにあたって書きのページを参考にさせて頂きました。

モデルの記述例

店舗に対して商品データが複数紐付く場合は $hasMany を使用します。具体的な書き方は以下のような感じです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Shop extends AppModel
{
    public $hasMany = Array(
        'Item' => Array(
            'className' => 'Item',
            'foreignKey' => 'shop_id',
            'order' => Array('Item.created DESC'),
            'dependent' => true
        ),
    );
 
    public function get_shop($shop_id)
    {
        $this->recursive = 2;
        $this->hasMany['Item']['conditions'] = Array(
            'Item.state' => 0,
            'Item.shop_id' => $shop_id
        );
        $result = $this->find('all', Array('conditions' => Array('id' => $shop_id)));
        return $result;
    }
}

$hasMany では conditions という、商品データに対する条件を設定することができます。limit なども設定することができます。詳細の設定例などについてはドキュメントが参考になります。

今回の例はショップを取り出す際に現在販売されている商品も取り出す (Item.state = 0) という記述になっていますが、売り切れた商品も一緒に取り出す場合もあるため、モデルのメンバ変数宣言時の設定には conditions の設定を省いています。もちろん事前に記述しておいて、必要な場合にメンバ変数の conditions の値を書き換えても実現可能です。

データを取り出す

データを取り出してみます。モデル内にある get_shop() はショップデータを取り出す時に、同時に商品データも取り出すメソッドです。このコードを実行すると以下のようなデータが取り出せます。(サンプルなので実際に取り出せるデータから不要な値を除去して見やすくしています。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Array
(
    [1] => Array
        (
            [Shop] => Array
                (
                    [id] => 1
                    [name] => 店舗名称
                )
 
            [Item] => Array
                (
                    [0] => Array
                        (
                            [id] => 1
                            [shop_id] => 1
                            [name] => 商品名1
                        )
                    [1] => Array
                        (
                            [id] => 2
                            [shop_id] => 1
                            [name] => 商品名2
                        )
                    [2] => Array
                        (
                            [id] => 3
                            [shop_id] => 1
                            [name] => 商品名3
                        )
                )
        )
)

おわりに

商品データにカテゴリやタグなどのモデルの関連付けがされていれば、そのデータも商品と一緒に (商品データの下にデータが紐付く形で) 取り出すことができます。ただ、あまりたくさんのデータを同時に取り出そうとすると遅くなりますので、$this->recursive の値を変更して、取り出す深度を調整しましょう。

コメント

コメントは受け付けていません。