I am using the following functions in my Contact model
public static function getParents()
{
return $this->hasMany(Contact::className(), ['parent_id' => 'id']);
}
I want to get the return of this array in the filter attribute of my view:
[
'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'
],
but I get the following error: Call to undefined method common\models\Contact::parents()
the rest of the relations work fine for example the attribute $model->parent
I was using the following code but it is wrong because dosn't brings the name of the parent_id within the same table but the name of the records with parent_id
'filter' => ArrayHelper::map(Contact::find()->where(['<>', 'parent_id', 0])->orderBy('name')->asArray()->all(), 'id', 'name'),
I managed to fix my filter using 2 queries in the form but is not very elegant:
$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')
UPDATED AFTER CORRECT ANSWER
I put the logic in the module to reuse it in other places and used getParentsArray instead of just 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;
}
in views or controllers
$parents = Contact::getParentsArray();
I think that your problem is this; You are using the method Contact::parents()
but this method doesn't exist in your model. You have declared a method getParents()
, which allows Yii to use the magic getter method to access the parents
as Contact::parents
.
There is a subtle but important difference in how Yii uses these two functions which will affect how you use them to generate an array suitable for use in your dropdown list:
The first, Contact::parents()
uses the relationship you've declared to get all the parent records. It returns an array of models of class Contact
, as you've declared in your method.
The second way is to directly call the static method getParents()
. This has the advantage that it returns an instance of ActiveQuery
, which then allows you to use the asArray()
and all()
methods associated with ActiveQuery
.
So, for your use case, I would put some more code in the model to generate your dropdown. The advantage of this is that it keeps model logic (which this is) inside the model, and it also then becomes reusable in other situations.
So, in your model, create this method;
public static function getParentsArray(){
return ArrayHelper::map(self::getParents()->asArray()->all(), 'id', 'name');
}
You can then use this in your view file like so;
'filter' => Contact::parentsArray()