LoginSignup
2
1

More than 5 years have passed since last update.

[CakePHP 3.x] 孫要素の保存メモ

Last updated at Posted at 2018-12-21

例として1つの注文 (Orders) に対して、複数のパッケージ (Packs) 、さらにその中に複数の商品 (Items) が入っている構造を考える。今回は一画面でこれらを一気に作成して保存までやってしまいたい

まずはEntityに対してassociationルールを設定する。今回はOrders と Packs, Packsと Itemsの間に hasMany 関係があるため親要素となるTableにそのルールを記述する。

OrdersTable.php
...(前略)
public function initialize(array $config)
{
    $this->hasMany('Packs', [
        'foreignKey' => 'order_id'
    ]);
}
...(後略)
PacksTable.php
...(前略)
public function initialize(array $config)
{
    $this->hasMany('Items', [
        'foreignKey' => 'pack_id'
    ]);
}
...(後略)

テンプレートは以下のように書く。 cake bake template order で生成されたものをベースにするといい。子要素、孫要素の名前の後に .[数字] を入れると数字ごとに関連づいて保存される。

Orders/add.php
<?= $this->Form->create($order) ?>
<?= $this->Form->control('name') ?>
<?= $this->Form->control('date') ?>
<?= $this->Form->control('packs.0.name') ?>
<?= $this->Form->control('packs.0.items.0.name') ?>
<?= $this->Form->control('packs.0.items.1.name') ?>
<?= $this->Form->control('packs.1.name') ?>
<?= $this->Form->control('packs.1.items.0.name') ?>
<?= $this->Form->control('packs.1.items.1.name') ?>
<?= $this->Form->control('packs.1.items.2.name') ?>
<?= $this->Form->end() ?>

add アクションの中でリクエストを表示するとこんな感じ

OrdersContoroller.php
function add() {
    var_dump($this->request->getData());
}

/* 出力結果
[
    "name" => "ほげほげ",
    "date" => "2018-12-21",
    "packs" => [
        0 => [
            "name" => "hogehoge",
            "items" => [
                0 => [
                    "name" => "ほげほげ"
                ],
                1 => [
                    "name" => "ほげほげ"
                ]
            ]
        ],
        1 => [
            "name" => "hogehoge",
            "items" => [
                0 => [
                    "name" => "ほげほげ"
                ],
                1 => [
                    "name" => "ほげほげ"
                ],
                2 => [
                    "name" => "ほげほげ"
                ]
            ]
        ]
    ]
]
*/

保存するときもassociationルールを設定する必要があるので注意

OrdersController
$order = $this->Orders->newEntity();
$order = $this->Orders->patchEntity($order, $this->request->data, [
    'associated' => [
        'Packs' => [
            'associated' => [
                'Items'
            ]
        ]
    ]
]);
$this->Orders->save($order)

これで保存が完了する。
デフォルトのpatchEntityだと子要素までしか見てくれないみたいなので、
patchEntity に association ルールを書くと孫要素までEntityとして変換してくれる。

saveした段階でEntityになると勘違いしてsaveメソッドにassociationルールを書いて詰まったのでメモしておく

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1