docs说:带有外键的模型将保存到数据库中而不进行验证。
但如果我想在
之前使用验证$order->link('items', $item);
够了吗?
if ($order->validate() && $item->validate())
{
$order->link('items', $item);
} else {
//do something
}
还是有其他解决方案?
答案 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);
这里要注意的两件事是:
$customer
和$order
共享one_to_many
关系。$customer
对象,这意味着它已经存在
存在并拥有有效的主键
link
需要使用方法来关联2个模型。这解释了同一文档中的小注:
注意:您无法链接两个新创建的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方法时的关键规则是要弄清楚(依赖于要链接的两个模型之间的关系类型)修改应在数据库中进行,并根据它进行验证。