cakePHP首次保存数据(hasMany关系)

时间:2012-12-03 22:26:48

标签: cakephp

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

我只是想朝着正确的方向前进,我不顾一切地学习,但想到用我的头在墙上钻一个洞看起来越来越诱人。

只是一点背景我有两个表“供应商”表和“vendor_payment_types”表。 “供应商”表中有很多“vendor_payment_types。结构如下:

供应商表 id,company_id,name

vendor_payment_types id,vendor_id,type

目前我发送给控制器的数组是(如果支付类型有一个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
    )
);

我甚至没有开始解决删除部分,因为我无法添加新的vendor_types。在无数的“尝试”中度过了美好的一天,所有的一切都没有发现。

感谢您一百万次的帮助!

1 个答案:

答案 0 :(得分:0)

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

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

因此VendorPaymentType不是供应商数据的一部分。为了进一步混淆你,更深层次的关联应该是'父'数组的一部分。

另外:

  • 您不必在VendorPaymentType记录中重复供应商的ID
  • 你不应该使用型号名称VendorPaymentType(singular)?
  • 在您的代码中,您可以立即保存所有供应商。如果在foreach循环中放入saveAssociated调用,则可以使自己更容易。如果需要(并使用InnoDB),您可以将其包装在事务中。
  • 如果一次保存关联太难,您可以保存供应商,然后保存到de VendorPaymentType的更改,如果需要则创建新的。在一个循环中,可能在一个事务中。

希望这会有所帮助。 : - )

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