[英]yii2: validate() before link()
docs说:带有外键的模型将被保存到数据库中,而无需执行验证。
但是如果我想在之前使用验证
$order->link('items', $item);
足够?
if ($order->validate() && $item->validate())
{
$order->link('items', $item);
} else {
//do something
}
还是有其他解决方案?
docs中有一个很好的例子:
$customer = Customer::findOne(123);
$order = new Order();
$order->subtotal = 100;
// without link()
$order->customer_id = $customer->id;
$order->save();
改为使用链接方法时,将其减少为:
$customer = Customer::findOne(123);
$order = new Order();
$order->subtotal = 100;
// with link()
$order->link('customer', $customer);
这里要注意的两件事是:
$customer
和$order
这两个模型共享一个one_to_many
关系。 $customer
对象是从数据库中检索到的,这意味着它已经存在并且具有链接方法需要使用的有效主键才能关联这两个模型。 这解释了同一文档中的小注释:
注意:您不能链接两个新创建的Active Record实例。
在该示例中,我们仅保存$order
对象。 因此,是的,首先以您的方式进行验证是有意义的,但没有$customer
情况就已经存在,因此我们将不会对其进行任何更改:
if ($order->validate()) {
$order->link('customer', $customer);
} else {
//do something
}
现在回到您的示例。 如果我没有记错的话,我们通常会看到订单及其项目之间的many_to_many
关系通常是many_to_many
关系。 这是完全不同的情况,因为两个模型都应该已经存在且主键值不为空。 否则,您将在其源代码中看到一个异常:
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.');
}
在这种情况下,链接两个模型是在相关联结表中插入新行的过程,您还可以在链接 $ extraColumns 属性内传递附加列值( 例如,quantity,total_price,.. ),如果失败,则为异常将被抛出。
因此,在那种特殊情况下,验证两个已经存在的模型毫无意义。 仅当您有更多数据要插入联结表中并且通常与要链接的两个模型不同时,才应该关心验证。
我认为使用链接方法时的关键规则是弄清楚(取决于要链接的两个模型之间的关系类型 )应该在数据库中进行哪些修改并基于该数据库执行验证。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.