-1

Assume this schema:

  • category(id, name)
  • article(id, categoryId, writerId, title, content)
  • writer(id, name, age, location)

I want to be able to get all articles written by a specific writer if i am starting at the category level. That is category > writer > articles, the articles should be only those belonging to the category.

Category Model:

class Category extends ActiveRecord
{
    ...
    public function getArticles()
    {
        return $this->hasMany(Article::className(), ['categoryId' => 'id']);
    }

    public function getWriters()
    {
        return $this->hasMany(Writer::className(), ['id' => 'writerId'])->via('articles');
    }
}

Writer Model:

class Writer extends ActiveRecord
{
    ...
    public function getArticles()
    {
        return $this->hasMany(Article::className(), ['writerId' => 'id']);
    }

    public function getCategories()
    {
        return $this->hasMany(Category::className(), ['id' => 'categoryId'])->via('articles');
    }
}

Article Model:

class Article extends ActiveRecord
{
    ...
    public function getCategory()
    {
        return $this->hasOne(Category::className(), ['id' => 'categoryId']);
    }

    public function getWriter()
    {
        return $this->hasOne(Writer::className(), ['id' => 'writerId']);
    }
}

If i do the following:

$category = Category::find()->with(['writers'])->where(['id' => 1])->one();
var_dump($category->writers[0]->articles);

All articles that writers[0] will be returned regardless the category. How do i make it return only for the category.id = 1.

SiZE
  • 1,966
  • 1
  • 11
  • 21
user2707590
  • 836
  • 10
  • 26

2 Answers2

1

try this

$category = Category::find()->where(['id' => 1])->one();
if ($category !== null) {
    $articles = $category->articles;
    if ($articles !== null) {
        foreach ($articles as $article) {
            if ($article->writer !== null) {
                var_dump($article->writer);
            }
        }
    }
}
cetver
  • 7,930
  • 5
  • 31
  • 50
0

I couldn't test it, but it might look similar to this:

$writers = Category::find()->where(['id' => $id])->one()->getWriters()->all();
$articles = [];
foreach ($writers as $writer) {
  $articles[] = $writer->getArticles()->all();
}
stig-js
  • 1,951
  • 12
  • 24