Answer the question
In order to leave comments, you need to log in
Yii2 dependent tables, how do you do without an additional model?
In general, there are 2 tables
book and genre
and there is a many-to-many relationship between them, so I add a pivot table genre-book
and in order to make standard calls I have to call forever $model->genres, this is if I call from the book model, but what if I have to look for books from genres, I will pass the function some( Book $item ) to the widget and it turns out that the model of the dependent GenreBook table
comes there and I have to write $model->book->title
how can I bypass the book call while having the right data?
example excerpt from my RecommendedBook code:
public function renderItem($item)
{
$title = $item->book->title();
$cardContent = '';
$imgSrc = '/img/book-thumb/'.rand(1,100).'.jpg';
$author = $item->book->author()[0]['first-name'].' '.$item->book->author()[0]['last-name'];
$cardContent .= Html::img($imgSrc,['class' => 'card-img-top']);
$cardContent .= Html::tag('h4',$title,['class' => 'card-title']);
$cardContent .= Html::tag('small',$author,['class' => 'text-muted']);
$cardDiv = Html::tag('div',$cardContent,['class' => 'card-block']);
return Html::a($cardDiv,['book/'.$item->book->url],$this->cardOptions);
}
$model = Book::find()->where( [ 'url' => $url ] )->limit( 1 )->one();
foreach ( $model->genres() as $genre ) {
$search = new GenreBookSearch();
$dataProvider[$genre['@attributes']['title']] = $search->search(Yii::$app->request->queryParams);
$dataProvider[$genre['@attributes']['title']]->query->andWhere(['genre_id' => $genre['@attributes']['id']]);
}
Answer the question
In order to leave comments, you need to log in
Your question is very difficult to understand.
As I understand it, you want to write shorter and clearer?
Moreover, to avoid errors, you will probably have to write not $item->book->title, but something similar to !empty($item->book)?$item->book->title:''
As I understand it, you have a problem in building a model and perhaps not knowing what hasMany and hasOne are (the link to the documentation and examples of use was discussed on the same site ), and you may not know such a phenomenon as magic methods , and specifically __get ().
So you should have something like this:
class Genre extends ActiveRecord
{
public function getBooks()
{
return $this->hasMany(Book::className(), ['id' => 'book_id'])
->viaTable('genre_book', ['genre_id' => 'id']);
}
}
You here , specifically viaTable(). The result should be for both $book->genres books and $genre->books genres. And to create a separate model for a linking table that does not carry additional information is usually not constructive.
It's not entirely clear what the question is... If you want to do without calling $item->book inside the renderItem function, do it like this
public function renderItem($book)
{
//какой-то код...
$title = $book->title();
$author = $book->author()[0]['first-name'].' '.$book->author()[0]['last-name'];
//какой-то код...
}
renderItem($item->book)
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question