3

在查看其他人的代码、指南、教程等时,我还没有在网上看到这个。

当我使用 Gii 生成模型时,关于关系的函数后面都有一个零。


例子:

class Benefit extends \yii\db\ActiveRecord
{
    // truncated Yii Model code...

    public function getType0()
    {
        return $this->hasOne(BenefitTypes::className(), ['id' => 'type']);
    }
}

BenefitTypes 是一个 id 到名称的映射:

id | name
---------------
1  =>  Federal
2  =>  Non-Profit

在“benefit”表中,它有一个名为“type”的列,它与“benefit_types”表的“id”列有关。

我虽然我应该能够做到(在/views/benefit/index.php)'type.name',但它也不起作用。它将列名称更改为“类型名称”并将“(未设置)”放入数据表中......

例子:

<?= DetailView::widget([
    'model' => $model,
    'attributes' => [
        'id',
        'somevalue',
        'type.name',
    ],
]) ?>

发生了什么事,为什么它的行为不像它应该的那样?


更新

我开始认为关系函数名称的 0 后缀,即:getType0,是由于表中使用“类型”作为列名以避免重复或混淆。虽然我找不到这个记录,所以想对此有一个明确的答案。

我将函数名称更改为 getTypeRelation()。然后在 index.php 视图中,对于 detailview 小部件,使用了“typeRelation.name”,它通过关系返回名称就好了。

4

2 回答 2

2

你的想法是正确的。关系名称的生成由函数generateRelationName()完成。

protected function generateRelationName($relations, $table, $key, $multiple)
{
    if (!empty($key) && substr_compare($key, 'id', -2, 2, true) === 0 && strcasecmp($key, 'id')) {
        $key = rtrim(substr($key, 0, -2), '_');
    }
    if ($multiple) {
        $key = Inflector::pluralize($key);
    }
    $name = $rawName = Inflector::id2camel($key, '_');
    $i = 0;
    while (isset($table->columns[lcfirst($name)])) {
        $name = $rawName . ($i++);
    }
    while (isset($relations[$table->fullName][$name])) {
        $name = $rawName . ($i++);
    }
    return $name;
}

Yii 使用相关表的名称作为关系名称。如果你有一个与相关表同名的列,一个数字将被附加到关系中以避免由于 Yii 处理魔术函数而造成的混淆。如果您在同一个表相关的单个表中有两列或更多列,例如列create_user_idupdate_user_id并且delete_user_id与表相关user将导致关系命名为和user,也会发生这种情况。user0user1

对于您的示例,建议将您的外键字段命名为其他名称,例如type_idor typeId。Yii 会正确处理这些。当您有多个与同一个表相关的列时,另一种选择是重命名函数。

于 2015-04-27T07:12:21.163 回答
0

因为关系列名和关系名是相同的。当您调用$benefit->type您所期望的值时,列/属性的值typeBenefitTypes? 所以现在你知道了。$benefit->type返回属性值并$benefit->type0返回关系实例。

于 2015-09-29T06:45:07.250 回答