I am having a yii2 error : common\models\Book has no relation named "favorite".
When I try to add:
public function search($params) {
$query = Book::find();
$query->joinWith(['author', 'profile', 'favorite']);
In the book model I do have the public function:
public function getFavoritedIcon() {
if (isset($this->favorite)) {
return '<i class="glyphicon glyphicon-asterisk books-form"></i>';
} else {
return '';
}
}
And also this extra function to get the icon
public function getFavoritedIcon() {
if (isset($this->favorite)) {
return $icon;
} else {
return '';
}
}
And this works fine in the grid where I want to add sorting and filter:
[
'label' => 'Favorites',
'attribute' => 'favorite',
'value' => 'favoritedIcon',
'hAlign' => 'center',
'vAlign' => 'middle',
'format' => 'raw',
'width' => '50px',
],
I do some different things from another models I am using:
abstract class Favorite extends \yii\db\ActiveRecord {
public static function tableName()
{
return 'user_favorite';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['user_id', 'book_id'], 'required'],
[['user_id', 'book_id'], 'integer'],
[['selectedTime'], 'safe']
];
}
Any clues what I am doing wrong ?
======================================================
UPDATE after Pedro del Sol answer
There was some errors in the code but the main one was answered by Pedro, I do had a favorite function in the Book model but not favorites with multiple output.
So now it is working like that:
In the Book model
public function getFavorite() {
$userID = Yii::$app->user->identity->id;
return Favorite::find()->where(['user_id' => $userID, 'book_id' => $this->id])->one();
}
public function getFavorites() {
$userID = Yii::$app->user->identity->id;
return $this->hasMany(Favorite::className(), ['book_id' => 'id'], ['book_id' => $this->id]);
}
public function getFavoritedIcon() {
if (isset($this->favorite)) {
return '<i class="glyphicon glyphicon-asterisk books-form"></i>';
} else {
return '';
}
}
In the BookSearch model:
public function search($params) {
$query = Book::find();
$query->joinWith(['favorites']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->setSort([
'attributes' => [
'title',
'author_id',
'rights_owner_id',
'user_favorite.user_id',
]
]);
and the grid view :
[
'label' => 'Favorites',
'attribute' => 'user_favorite.user_id',
'value' => 'favoritedIcon',
'hAlign' => 'center',
'vAlign' => 'middle',
'format' => 'raw',
'width' => '50px',
],
Having a method to getFavoritedIcon()
is not the same as declaring a relation to getFavorite()
I assume that in your Book
model class you have the methods getAuthor()
and getProfile()
which will return queries linking a Book
with an Author
and a Profile
. You'll need something similar with Favorite
(s) but I suspect the multiplicities will be different.
I think to declare your relation you'll need something like
/**
* @return \yii\db\ActiveQuery
*/
public function getFavorites()
{
return $this->hasMany(Favorite::className(), ['book_id' => 'ID']);
}
if the relation between Book
s and Favorite
s is one to many (most likely) or
/**
* @return \yii\db\ActiveQuery
*/
public function getFavorite()
{
return $this->hasOne(Favorite::className(), ['book_id' => 'ID']);
}
if the relation is one to one.
You can then use joinWith()
with either 'favorite' or 'favorites' depending on the multiplicities of your relation.