我有这个架构:
和模型zwz
中的这种关系:
public function getAuftrs() {
return $this->hasMany(\app\models\Auftr::className(), ['id' => 'auftr_id'])
->viaTable('znw', ['zwzx_id' => 'id'])
->viaTable('zwz_expl', ['zwz_id' => 'id'])
;}
在zwz
:的视图中
<?= count($model->getAuftrs()->asArray()->all())
我得到了:
PHP注意 - yii \ base \ ErrorException
未定义的索引:auftr_id
C中的
- :... \ vendor \ yiisoft \ yii2 \ db \ ActiveRelationTrait.php
醇>
现在,如果我将两个viaTable()
更改为:
->via('znws')
当然在以前定义这种关系:
public function getZnws() {
return $this->hasMany(\app\models\Znw::className(), ['zwzx_id' => 'id'])
->viaTable('zwz_expl', ['zwz_id' => 'id'])
;}
然后它的工作原理。
问题是,后一种via()
方法与 yii2-giiant 不兼容,所以我想知道两者之间的实际区别是什么,我怎么能保留原始{ {1}}方式。
对我而言,似乎很清楚我们总是必须选择链的最后一个ID并向后定义所有其他ID。 (但是在这些文档中有viaTable()
而不是via()
,也许它也有区别)
提前致谢!
答案 0 :(得分:1)
您不能在同一关系上使用viaTable()
两次。第二个调用将覆盖第一个调用。如果您想要超过联结表,则需要via()。但是,您可以定义多个关系,其中一个使用via()
,另一个使用viaTable()
。
我不知道giiant是如何工作的,但它可能通过使用viaTable()
的事实来检测许多关系。与viaTable()
相比,via()
会跳过一个表,因此您不需要ActiveRecord作为联结表。使用via()
,您始终可以定义直接关系。
关于关系定义中键的顺序,请查看
中的文档http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#declaring-relations
[...]两种类型数据之间的链接:指定两种类型数据相关的列。数组值是主数据的列(由您声明关系的Active Record类表示),而数组键是相关数据的列。
一个容易记住的规则是,正如您在上面的示例中看到的那样,您直接在其旁边写下属于相关活动记录的列。您看到customer_id是一个属性Order和id是客户的财产。