Search code examples
phpyii2yii2-model

Yii2 Model ViaTable


For simplicity, lets say I have 3 tables: menu, page and a junction table menu_page.

So If I want to get all menus which are available for page "home", in the model I defined a relationship:

public function getAllMenus() {
    return $this->hasMany(Menu::className(), ['id' => 'menu_id'])->viaTable(PageMenu::tableName(), ['page_id' => 'id']);
}

But now we have added an attribute to menu table called show_all_pages, if this is set as 1, menu should be returned, if not we should check if menu is enabled to be used on home.

Is there a way to add this condition here?


Solution

  • The solution I found so far was doing to separate Active Queries and do a Union:

    public function getSelectedMenus() {
    
            return $this->hasMany(Menu::className(), ['id' => 'menu_id'])->viaTable(PageMenu::tableName(), ['page_id' => 'id'])->onCondition(['menu.active' => Page::ACTIVE]);
        }
    
        public function getAllMenus() {
            return Menu::find()->where(['active' => Page::ACTIVE, 'show_all_pages' => 1]);
        }
    
        public function getMenus() {
    
            $selectedMenus = $this->getSelectedMenus();
            $allMenus = $this->getAllMenus();
    
            return $selectedMenus->union($allMenus);
    
        }