【问题标题】:Yii2 - Gii Model Relations - Why is there a 0 after the function names?Yii2 - Gii 模型关系 - 为什么函数名后面有 0?
【发布时间】:2015-09-29 14:45:07
【问题描述】:

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

当我用 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,是由于在表中使用“type”作为列名以避免重复或混淆。虽然我找不到这个记录,所以想对此有一个明确的答案。

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

【问题讨论】:

    标签: php yii2 gii


    【解决方案1】:

    你的想法是正确的。关系名称的生成由函数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 处理魔术函数而造成的混淆。如果您在与同一个表相关的单个表中有两列或更多列,也会发生这种情况,例如与表user 相关的列create_user_id、update_user_id 和delete_user_id 将导致名为user、user0 的关系和user1。

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

    【讨论】:

    • 我将此标记为答案。我在 GitHub 上的源代码中找到了您正在谈论的功能,并认为这就是它的要点。现在,这不仅发生在“类型”上,它也发生在其他列上,导致 'getCategory0' 和 'getBenefit0' 不是 Yii 函数或变量,只是我的列的名称。我将它们更改为喜欢“getCategoryRelation”并分别使用它们,没有任何问题。我认为将 Relation 添加到最后可以使代码更好,因为我知道它的真正含义。
    【解决方案2】:

    因为关系列名和关系名是一样的。当您调用$benefit-&gt;type 时,您会期望得到type 的列/属性的值还是BenefitTypes 的实例?所以现在你知道了。 $benefit-&gt;type 返回属性值,$benefit-&gt;type0 返回关系实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-09
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 2015-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多