0

我在我的联系人模型中使用以下功能

public static function getParents()
{
    return $this->hasMany(Contact::className(), ['parent_id' => 'id']); 
}

我想在我的视图的过滤器属性中返回这个数组:

        [
        'attribute' => 'parent_id',
        'value' => function ($model) {
            return $model->parent ? $model->parent->name : null;
        },
        'hAlign' => 'left',
        'vAlign' => 'middle',
        //'filter' => ArrayHelper::map(Contact::find()->where(['<>', 'parent_id', 0])->orderBy('name')->asArray()->all(), 'id', 'name'),
        'filter' => ArrayHelper::map(Contact::parents()->asArray()->all(), 'id', 'name'),
        'filterWidgetOptions' => [
            'pluginOptions' => ['allowClear' => true],
        ],
        'filterInputOptions' => ['placeholder' => 'Parent'],
        'format' => 'raw'
    ],

但我收到以下错误:调用未定义的方法 common\models\Contact::parents()

其余的关系工作正常,例如属性 $model->parent

我正在使用以下代码,但它是错误的,因为不会将 parent_id 的名称带到同一个表中,而是将带有 parent_id 的记录的名称

'filter' => ArrayHelper::map(Contact::find()->where(['<>', 'parent_id', 0])->orderBy('name')->asArray()->all(), 'id', 'name'),

我设法使用表单中的 2 个查询来修复我的过滤器,但不是很优雅:

$subQuery = Contact::find()->select('parent_id')->where(['<>', 'parent_id', 0]);
$parents = ArrayHelper::map(Contact::find()->where(['in', 'id', $subQuery])->orderBy('name')->asArray()->all(), 'id', 'name')

正确答案后更新

我将逻辑放在模块中以在其他地方重用它并使用 getParentsArray 而不仅仅是 parentsArray

public static function getParentsArray() {
    $subQuery = Contact::find()->select('parent_id')->where(['<>', 'parent_id', 0]);
    $parents = ArrayHelper::map(Contact::find()->where(['in', 'id', $subQuery])->orderBy('name')->asArray()->all(), 'id', 'name');
    return $parents;
}

在视图或控制器中

$parents = Contact::getParentsArray();
4

2 回答 2

1

我认为你的问题是这样的;您正在使用该方法Contact::parents(),但您的模型中不存在此方法。你已经声明了一个方法getParents(),它允许 Yii 使用魔法 getter 方法来访问parentsas Contact::parents

Yii 如何使用这两个函数有一个微妙但重要的区别,这将影响您如何使用它们来生成适合在下拉列表中使用的数组:首先,Contact::parents()使用您声明的关系来获取所有父记录。它返回一个类模型数组Contact,正如您在方法中声明的那样。

第二种方式是直接调用静态方法getParents()。这样做的好处是它返回一个 的实例ActiveQuery,然后允许您使用与关联的asArray()和方法。all()ActiveQuery

因此,对于您的用例,我会在模型中添加更多代码来生成您的下拉列表。这样做的好处是它将模型逻辑(这是)保留在模型中,然后它也可以在其他情况下重用。

因此,在您的模型中,创建此方法;

public static function getParentsArray(){
return ArrayHelper::map(self::getParents()->asArray()->all(), 'id', 'name');
}

然后,您可以像这样在视图文件中使用它;

'filter' => Contact::parentsArray()
于 2017-04-20T18:26:49.110 回答
0

Contact::parents()表达式正在调用parents()您的代码中不存在的静态方法。在这种情况下, parents() 不是关系。没有使用此表达式初始化的 QueryInterface。

对于您的任务,$dataProvider用作关联父母的基础。

'filter' => ArrayHelper::map($dataProvider->getModels()[0]->parents->find()->all(),'id','name'),

可能在这里你已经验证了$dataProvider进入第一级的大小。

于 2017-04-21T07:49:21.177 回答