【问题标题】:CakePHP - saving to more than two models using save associatedCakePHP - 使用保存关联保存到两个以上的模型
【发布时间】:2019-10-21 09:28:35
【问题描述】:

我正在尝试更复杂的东西。我有一个存储所有一般物品的项目,我有一个产品,它是一个项目,我有一个商品,它是一个产品和一个项目。所以我有一个输入商品价值的表格,它应该保存到所有与模型相关的表格(项目、产品、商品)中。有这么多表的原因是因为所有表都应该有一个稍后使用的 id,例如:product 应该有它的 id,稍后用于销售。这是控制器:

public function add() {
    $this->load();

    if ($this->request->is('post')) {

$this->Item->create();
        $this->request->data['Item']['code'] = $finalCode;
        $this->request->data['Item']['is_deleted'] = false;
        $item = $this->Item->save($this->request->data);

        if(!empty($item)){
            $this->request->data['Product']['item_id'] = $this->Item->id;
            $this->request->data['Good']['item_id'] = $this->Item->id;

            debug($this->request->data['Product']['item_id']);
            debug($item);

            $this->Item->Product->save($this->request->data);
            $this->request->data['Good']['pid'] = $this->Product->id;
            $this->Item->Good->save($this->request->data);
        }

        if($this->Good->validationErrors || $this->Item->validationErrors || $this->Product->validationErrors){
            //ERRORS
        }
        else{
            //FAILS
        }
    }
}

编辑:我已经更改了控制器,现在项目从未保存,但 Product 和 Good 已保存,并且它们都映射得很好,ID 没问题但 Item 甚至不在数据库中,尽管 Product 和 Good 将 item_id 设置为应该在数据库中的下一个值。

class Good extends AppModel {

    public $belongsTo = array(
        'Item' => array(
            'className' => 'Item',
            'foreignKey' => 'item_id',
        ),
        'Product' => array(
            'className' => 'Product',
            'foreignKey' => 'pid',
        )
    );
}

class Product extends AppModel {

    public $hasOne = array(
        'Good' => array(
            'className' => 'Good',
            'foreignKey' => 'pid',
            'dependent' => false,
        ),
    );
}

class Item extends AppModel{

    public $hasMany = array(
         'Good' => array(
        'className' => 'Good',
        'foreignKey' => 'item_id',
        'dependent' => false,
    ),
    'Product' => array(
        'className' => 'Product',
        'foreignKey' => 'item_id',
        'dependent' => false,
    ),
    );

}

即使调试后的 $item 看起来还可以,但没有保存:

array(
    'Item' => array(
        'name' => 'Microcontrollers',
        'description' => 'Wire Jumpers Female-to-Female 30 cm',
        'weight' => '22',
        'measurement_unit_id' => '7',
        'item_type_id' => '29',
        'code' => 'GOD-34',
        'is_deleted' => false,
        'modified' => '2019-10-22 12:37:53',
        'created' => '2019-10-22 12:37:53',
        'id' => '120'
    ),
    'Good' => array(
        'status' => 'development',
        'hts_number' => '8473 30 20',
        'tax_group' => '20%',
        'eccn' => 'EAR99',
        'release_date' => array(
            'month' => '10',
            'day' => '22',
            'year' => '2019',
            'hour' => '10',
            'min' => '10',
            'meridian' => 'am'
        ),
        'is_for_distributors' => '1'
    ),
    'Product' => array(
        'project' => 'neqwww'
    )
)

【问题讨论】:

  • 您确定要将ProductGood 以及Item 相关联吗?这通常没有什么问题,但是 CakePHP 不能自动处理,它只能保存一个方向的关联,即父母或孩子,你正在尝试保存兄弟数据集。 CakePHP 2.x 愚蠢的数据结构要求可能有点让人分心,但基本上Item 没有嵌套在Product 中,那是行不通的。您必须手动发出多个保存并相应地提供外键。
  • 好吧,我不太确定。所以你想说的是,它不能通过一笔交易来完成。如果我会这样做,我可以简单地首先保存一个项目而不是保存其他到并访问项目 ID,因为它被保存了。但我不确定如果不是在一笔交易中完成是不是很好。问题是,数据库设计本身可能存在缺陷。但是我有一个组织固定的项目,我找不到更好的设计。要求所有产品都有唯一的 id,由于产品可以是商品、服务等,它们唯一的唯一 id 是在 Items 中,所以也许可以。
  • 也许最好的解决方案是简单地删除 products 表,因为它看起来很多余。
  • 好吧,我真的不能给你任何建议,如果不了解全貌就很难说。但请注意,您可以手动发出交易:book.cakephp.org/2.0/en/models/transactions.html$this 在这种情况下是一个模型实例,您需要在保存调用中将atomic 选项设置为falsebook.cakephp.org/2.0/en/models/…

标签: php cakephp cakephp-2.3


【解决方案1】:

我认为问题在于您保存数据的行处的代码。

$this->Item->create();
$this->Good->create();
$this->Product->create();

$this 是什么?如果您使用“$this”创建项目,然后尝试创建“产品”,则“$this”将没有 item_id。

尝试使用类似的方法来保存创建的项目。

$item = $this->Item->create();

然后,在创建了 $item 之后,您可以使用 $item->id 创建一个 $product

更新:

来自 cakephp 文档。

// Create: id isn't set or is null
$this->Recipe->create();
$this->Recipe->save($this->request->data);

// Update: id is set to a numerical value
$this->Recipe->id = 2;
$this->Recipe->save($this->request->data);

您必须使用 $this->Item->save($data) 将信息保存到数据库中。

https://book.cakephp.org/2.0/en/models/saving-your-data.html

也许 create() 方法有点不清楚。用于重启模型状态。

原来如此

$item_saved = $this->Item->save($data['Item']);
$data['Product']['item_id'] = $this->Item->getLastInsertId();
$product_saved = $this->Product->save($data['Product']);

编辑 2:

可能是因为您在保存项目之前没有使用 create()。请试试这个:

$this->Item->create();
$item_saved = $this->Item->save($data['Item']);
$data['Product']['item_id'] = $this->Item->getLastInsertId();
$product_saved = $this->Product->save($data['Product']);

【讨论】:

  • 但是 CakePHP 应该自己连接这些 id,因为模型有所有的关系。即使我尝试设置 $item = $this->Item->create();后来为了调试它的值,它返回一个空数组。您的解决方案不起作用,因为 $item 不是对象,因为 Model::create() 不返回保存的对象,它只是将当前模型重置为其默认值。我可以使用 $this->data 返回要插入的正确数据,然后使用 $this->data['Product']['item_id'] 访问数据,但我没有将其设置为的值。如何在保存之前访问要插入的对象的 id。
  • 另外,$this->Item->id 只有在保存完成后才能访问,但我不能这样做,因为我应该将它们全部保存在一个事务中。
  • @МладенКарић 我编辑了我的答案,也许现在对你有用
  • 这是一个很好的方向,虽然现在Good和Product都保存了,但是Item没有,我已经更新了问题。
猜你喜欢
  • 1970-01-01
  • 2015-06-21
  • 1970-01-01
  • 2013-09-24
  • 2011-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多