多表关联一对多查询之hasMany
public function actionAbout() { $category = Category::findOne(1); $articles = Article::find()->where(['cate_id'=>$category->attributes['id']])->all(); var_dump($articles); }
上面的例子可以获取到文章cate_id等于分类id的所有文章,但是效率相对hasMany写法较低,下面看hasMany写法:
public function actionAbout() { $category = Category::findOne(1); $articles = $category->hasMany('app\models\Article', ['cate_id'=>'id'])->all(); var_dump($articles); } //hasMany()参数1:关联模型完整命名空间,参数2:模型间关联关系
上面的例子可以更加简便为:
public function actionAbout() { $category = Category::findOne(1); $articles = $category->hasMany(Article::className(), ['cate_id'=>'id'])->all(); var_dump($articles); }
上面的例子hasMany()是直接写在控制器中的,如果需要多次用到此方法,会产生耦合,规范的写法是将此方法方法模型中:
模型中:
class Category extends ActiveRecord { public function getArticles() { $articles = $this->hasMany(Article::className(), ['cate_id'=>'id'])->asArray()->all(); return $articles; } }
控制器中:
public function actionAbout() { $category = Category::findOne(1); $articles = $category->getArticles(); var_dump($articles); }
hasMany()第二种写法:
模型中:
class Category extends ActiveRecord { public function getArticles() { $articles = $this->hasMany(Article::className(), ['cate_id'=>'id'])->asArray(); return $articles; } }
控制器中:
public function actionAbout() { $category = Category::findOne(1); $articles = $category->articles; var_dump($articles); }
PS:通过调用articles属性,会自动走__get()魔术函数,__get()会自动补上get,变成getArcticles(),并且会自动判断到hasMany()在结尾加上all(),所以模型里不需要加all()也行,最后返回结果。