cakePHP 第一次保存数据(hasMany 关系)

问题描述 投票:0回答:1

好吧,我正在尝试我的第一个 saveAll (或 saveMany 或 saveAssociated 不确定哪个是“正确的”),其中包括 hasMany 关系,我似乎无法弄清楚 cake 如何需要这些数据。 我可以更新主表上的名称字段,但无法更新 hasMany 关系。

我只是在寻找正确方向的障碍,我迫切想学习,但用我的头在墙上打洞的想法看起来越来越诱人。

只是一点背景知识我有两个表,一个“vendors”表和一个“vendor_ payment_types”表。 “vendors”表有许多“vendor_ payment_types。结构如下:

供应商表 id、公司 ID、名称

供应商付款类型 id、vendor_id、类型

目前我发送到控制器的数组是(如果支付类型有一个id,意味着它已经存在于数据库中并且不需要发生任何事情,如果没有id则需要添加,第三部分是如果它存在于数据库中,但不存在于该数组中,需要从数据库中删除):

Array
(
[0] => Array
    (
        [Vendor] => Array
            (
                [id] => 7
                [company_id] => 2
                [name] => Test Vendor
                [VendorPaymentTypes] => Array
                    (
                        [0] => Array
                            (
                                [vendor_id] => 7
                                [id] => 13
                                [type] => payable
                            )

                        [1] => Array
                            (
                                [vendor_id] => 7
                                [type] => check
                            )

                        [2] => Array
                            (
                                [vendor_id] => 7
                                [id] => 14
                                [type] => cash
                            )

                    )

            )

    )

我需要做的是 a) 更新名称 b) 添加任何新的 VendorTypes c) 删除不在 POST 数组中但存在于数据库中的任何 VendorTypes。 以下是我的 VendorController 中的内容:

public function save() {
   $vendors = array();
    $companyid = $this->Auth->user('company_id');
    $needle = 'new';
    $i = 0;

    // Setup array and also if id of payment_type includes "new" unset the id so cake will add a new and not try and match id and update

    if ($this->request->is('post')) {
        foreach ($this->request->data['Vendor'] as $vendorId => $vendor) {
            $vendors[$vendorId]['Vendor']['id'] = $vendorId;
            $vendors[$vendorId]['Vendor']['company_id'] = $companyid;
            $vendors[$vendorId]['Vendor']['name'] = $vendor['name'];
            foreach ($vendor['VendorTypes'] as $type => $val) {
                if ($val != '0') {
                    $vendors[$vendorId]['Vendor']['VendorPaymentTypes'][$i]['vendor_id'] = $vendorId;
                    $vendors[$vendorId]['Vendor']['VendorPaymentTypes'][$i]['id'] = $val;
                    $vendors[$vendorId]['Vendor']['VendorPaymentTypes'][$i]['type'] = $type;

                    if (strstr($vendors[$vendorId]['Vendor']['VendorPaymentTypes'][$i]['id'], $needle)) {
                        unset($vendors[$vendorId]['Vendor']['VendorPaymentTypes'][$i]['id']);
                    }
                    $i++;
                }
            }
        }

        // Clean up array to make it an array starting at 0 and not based on vendor['id']

        $cleanedarr = array();
        foreach ($vendors as $vendor => $data) {
            $cleanedarr[] = $data;
        }

        // Currently this only updates the name

        if ($this->Vendor->saveAll($cleanedarr, array('deep' => TRUE) )) {
            $this->Session->setFlash('Updated Vendors!');
            die(pr($this->Vendor->getDataSource()->getLog()));
        } else {
            $this->Session->setFlash('Failed to Update');
        }
    }
}

供应商模型设置为

public $name = 'Vendor';

public $hasMany = array(
    'VendorPaymentTypes' => array(
        'className' => 'VendorPaymentTypes',
        'foreignKey' => 'vendor_id',
        'dependent' => true
    )
);

我什至还没有开始处理删除部分,因为我无法添加新的供应商类型。 度过了美好的一天,进行了无数次“尝试”,但都一无所获。

感谢您一百万次的帮助!

php cakephp
1个回答
0
投票

关联的日期(供应商类型)不应该是供应商数据内部的数组,而应该是外部的数组。

array(
    'Vendor' => 
           array('name' => 'test', 'id' => 7),
    'VendorPaymentType => array(
         array('id' => 13, 'type' => 'payable'),
         array('type' => 'check')
    )
);

因此 VendorPaymentType 不是 Vendor 数据的一部分。为了进一步迷惑您,更深层次的关联应该是“父”数组的一部分。

还有:

  • 您不必在 VendorPaymentType 记录中重复 Vendor id
  • 您不应该使用模型名称 VendorPaymentType (单数)吗?
  • 在您的代码中,您一次保存所有供应商。如果您将 saveAssociated 调用放在 foreach 循环内,您可以让自己更轻松。如果需要(并使用 InnoDB),您可以将其包装在事务中。
  • 如果一次保存关联太困难,您可以只保存供应商,然后保存对 VendorPaymentType 的更改,并在需要时创建新的关联。在循环中,可能在事务内。

希望这有帮助。 :-)

另请参阅:http://book.cakephp.org/2.0/en/models/ saving-your-data.html

© www.soinside.com 2019 - 2024. All rights reserved.