yii2:在链接()之前的validate()

时间:2016-03-19 16:48:51

标签: php activerecord yii2

docs说:带有外键的模型将保存到数据库中而不进行验证。

但如果我想在

之前使用验证
$order->link('items', $item);

够了吗?

if ($order->validate() && $item->validate())
{
    $order->link('items', $item);
} else {
//do something
}

还是有其他解决方案?

1 个答案:

答案 0 :(得分:3)

docs中有一个很好的例子:

$customer = Customer::findOne(123);
$order = new Order();
$order->subtotal = 100;

// without link()
$order->customer_id = $customer->id;
$order->save();

使用link方法改为:

$customer = Customer::findOne(123);
$order = new Order();
$order->subtotal = 100;

// with link()
$order->link('customer', $customer);

这里要注意的两件事是:

  1. 2个模型$customer$order共享one_to_many 关系。
  2. 从DB中检索$customer对象,这意味着它已经存在 存在并拥有有效的主键 link 需要使用方法来关联2个模型。
  3. 这解释了同一文档中的小注:

      

    注意:您无法链接两个新创建的Active Record实例。

    在该示例中,我们只会保存$order个对象。所以是的,首先以你的方式验证它是有意义的,但不是$customer,因为它已经存在,我们不会改变任何内容:

    if ($order->validate()) {
      $order->link('customer', $customer);
    } else {
    //do something
    }
    

    现在回到你的例子。如果我没有错,我们习惯在订单商品之间看到的社区关系通常是many_to_many关系。这是一个完全不同的情况,因为两个模型应该已经存在且不是主键值。否则,您将在其source code

    中看到异常
    if ($relation->via !== null) { // -> many_to_many relation
        if ($this->getIsNewRecord() || $model->getIsNewRecord()) {
            throw new InvalidCallException('Unable to link models: the models being linked cannot be newly created.');
        }
    

    在这种情况下链接两个模型是在相关的junction table中插入新行的过程,您还可以在其中传递其他列值(可能是数量,total_price,.. link $ extraColumns 属性内,如果失败则会抛出异常。

    因此,在这种特殊情况下,验证两个已存在的模型是没有意义的。只有当您在联结表中插入更多数据并且通常与您链接的两个模型不同时,才应关注验证。

    我认为使用link方法时的关键规则是要弄清楚(依赖于要链接的两个模型之间的关系类型)修改应在数据库中进行,并根据它进行验证。