voskobovich/yii2-many-to-many-behavior

Custom Getters/Setters Specify Column

Closed this issue · 1 comments

Your extension is great -- and extraordinarily powerful, yet so easy to use. I've managed to do these kinds of many-to-many saves and updates and suffered greatly each time. I can really appreciate all the effort it took to get this behavior working. I have a question on using custom getters and setters.

Basically, I've got a categories table that has id and name columns in addition to other columns. I've implemented custom getters and setters as described in your instructions, and it works just fine, except that what the string version is returning is a string of ids. What I need is a string of names, the second column in the table. How can I specify that I want to implode the name column instead of the id column. What I'm looking at here is what is displayed in GridView.

It's interesting that, when I use the relation name in the _form field, it displays a delimited string of names. Of course, that's working off a data list that I supply for the dropdown. However, when I use the very same relation name in GridView, I get an error saying that it's getting an array and expects a string. When I set up your custom getters and setters and use categories_string as the column in GridView, there are no errors, but it displays a string of ids.

So you need to have a column in your grid view that shows all categories as text? Custom getters and setters are not the solution, because the text label you need to get is not available in the getter/setter function context (only the ID is available). Fortunately, this problem is easily solved using standard yii2 functionality.

So, in your model you have this relation:

public function getCategories()
{
    return $this->hasMany(Category::className(), ['id' => 'category_id'])
        ->viaTable('article_has_category', ['article_id' => 'id']);
}

Add the following getter:

public function getCategoriesAsText()
{
    return implode(', ', ArrayHelper::getColumn($this->categories, 'name'));
}

And just use it in your grid view.