【问题标题】:yii2 via() vs viaTable()yii2 via() 与 viaTable()
【发布时间】:2017-10-25 15:26:47
【问题描述】:

我有这个架构:

以及模型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

  1. 在 C:...\vendor\yiisoft\yii2\db\ActiveRelationTrait.php 中

现在如果我将两个 viaTable()s 更改为:

->via('znws')

当然还要先定义这个关系:

public function getZnws() {
    return $this->hasMany(\app\models\Znw::className(), ['zwzx_id' => 'id'])
        ->viaTable('zwz_expl', ['zwz_id' => 'id'])
;}

然后就可以了。 问题是,后者via() 方式与yii2-giiant 不兼容,所以我想知道两者之间的实际区别是什么,以及如何保留原来的viaTable()方式。

github.com/yiisoft/yii2/.../docs/guide/db-active-record.md#chaining-relation-definitions-via-multiple-tables

对我来说,似乎很清楚我们总是必须选择链的最后一个 ID 并向后定义所有其他 ID。 (但是在这些文档中有via() 而不是viaTable(),也许它也会有所不同)

提前致谢!

【问题讨论】:

  • 能给我们看看zwz的型号吗
  • 其实我觉得我找到了问题所在。它与via和viaTable无关。问题是您正在使用模型中不存在的索引。如您所见,zwz 没有auftr_id 的表。
  • 您能告诉我如何通过多个表定义viaTable() 吗?如果我什至不必使用多个viaTable()s...怎么办?
  • 我的意思是,一旦我通过viaTable() 定义了第一个表,我就必须在该模型中定义下一个表,依此类推...?
  • 你可以尝试交换'auftr_id'和'id'

标签: yii2 yii2-giiant


【解决方案1】:
  1. 你不能在同一个关系上使用两次viaTable()。第二个调用将覆盖第一个调用。如果您想查看的不仅仅是连接表,您需要via()。但是,您可以定义多个关系,其中一个使用via(),另一个使用viaTable()

  2. 我不知道giiant 是如何工作的,但它可以通过使用viaTable() 来检测多对多关系。 viaTable()via() 相比跳过一个表,因此您不需要为联结表创建 ActiveRecord。使用via(),您始终可以定义直接关系。

  3. 关于关系定义中键的顺序,请查看文档

    http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#declaring-relations

    [...] 两种类型数据之间的链接:指定将两种类型的数据关联起来的列。数组值是主数据的列(由您声明关系的 Active Record 类表示),而数组键是相关数据的列。

    记住这一点的一个简单规则是,正如您在上面的示例中看到的那样,您将属于相关 Active Record 的列直接写在它旁边。您会看到 customer_id 是一个属性Order 和 id 是 Customer 的属性。

【讨论】:

  • 我也有同样的想法,也许viaTable() 在关系中只能使用一次,但我自己无法弄清楚。它可以在包含的文档中吗?或者有没有机会让 yii 与多个 viaTable()s 一起工作(当它有意义时)?
  • 我看不出您将如何定义与两次 viaTable 的关系。如果您在更高级别上描述问题,会更容易为您提供帮助。从用户的角度来看,您有哪些实体以及它们应该如何在高层次上关联。您的架构看起来也有点奇怪,因为没有可以证明 viaTable() 使用的多对多表,没有组合主键。
  • 我会像上面的例子那样定义它:zwz hasMany Auftr viaTable('znw'...) viaTable('zwz_expl'...) 是znw不是M :M 表?我只想要那个巨人为我生成相关数据。因此,当我查看zwz(视图)时,我希望能够看到所有相关的Auftrs。这个想法有问题吗?
  • M:M 表应该将​​主键作为两个外键列上的复合键。正如我所说,我不知道giiant 是如何工作的,但是如果你想遍历多个表,则必须使用 via() 来完成 Yii 中的关系定义。如果你想让giiant理解这一点,那可能是对它的功能要求。
  • 为什么 yii2 使用复合键而不是单个键更好(或者必须?)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
  • 2019-07-11
相关资源
最近更新 更多