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);
这里需要注意的两件事是:
-
$customer 和 $order 两个模型共享一个 one_to_many
关系。
-
$customer 对象已从 DB 中检索到,这意味着它已经
存在并且有一个有效的主键
link
需要使用方法来关联这 2 个模型。
这解释了同一文档中的那个小注释:
注意:您不能链接两个新创建的 Active Record 实例。
在那个例子中,我们只保存$order 对象。所以是的,首先按照您的方式验证它是有意义的,但不是$customer,因为它已经存在,我们不会对其进行任何更改:
if ($order->validate()) {
$order->link('customer', $customer);
} else {
//do something
}
现在回到你的例子。如果我没记错的话,我们通常在 order 和它们的 items 之间看到的公共关系通常是 many_to_many 关系。这是一个完全不同的情况,因为 both 模型应该已经存在且不具有 null primary key 值。否则将抛出异常,如您在其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 中插入新行的过程,您还可以在其中传递其他列值(可能是数量、总价格、..) link $extraColumns 属性,如果失败,将引发异常。
因此,在这种特殊情况下,验证两个已经存在的模型是没有意义的。只有当您在联结表中插入更多数据并且这通常是与您链接的两个不同的模型时,您才应该关心验证。
我认为使用link 方法时的关键规则是找出(取决于要链接的两个模型之间的关系类型)应该在哪里修改在数据库中创建并根据它执行您的验证。