仅选择具有相关模型的模型或具有相关模型的后代

时间:2012-04-18 11:32:00

标签: php sql activerecord yii

因此,有类别和产品,我需要选择非空的类别才能构建产品类别菜单。 非空表示类别包含产品或后代类别包含产品。我想用范围来做,但我似乎无法走远。

有点类似于以下内容,但我需要递归检查类别层次结构中的更多级别

/**
 * This is the model class for table "shopCategories".
 *
 * The followings are the available columns in table 'shop_categories':
 * @property integer $id
 * @property integer $parentId
 * @property integer $order
 * @property integer $isActive
 * @property integer $cstamp
 * @property integer $mstamp
 *
 * The followings are the available model relations:
 * @property ProductCategory $parent
 * @property ProductCategory[] $children
 * @property ProductCategoryL10n[] $l10n
 * @property ProductCategoriesProducts[] $productsJunction
 */
class ProductCategory extends BogoActiveRecord
{
...

public function nonEmpty()
{    
    $this->getDbCriteria()->mergeWith(array(
        'with' => array(
            'children',
            'children.products'=>array(
                'condition'=>'products.isActive=1',
                'joinType'=>'INNER JOIN', 'limit'=>1
            ),
        ),
    ));

    return $this;
}

...
}

2 个答案:

答案 0 :(得分:2)

递归是数据库真正不擅长的东西(例如,MySql根本不支持递归)。不幸的是,你不能直接提出要求。

您的选择是:

  1. 用PHP进行过滤。
  2. 修改数据库架构以使用modified preorder tree traversal(MPTT),更新模型并再次询问。

答案 1 :(得分:0)

如果您对产品设置了级别限制,那么您可以构建一次性查询以节省PHP处理时间。您可以通过使用别名将所需的连接数添加回同一个表来手动执行“递归”。

如果您被迫进入当前架构,那么这可能会避免重建查询,更不用说执行并将其抽象回Active Records,只是为了查看它们是否为空。

这假设您没有无限深的菜单结构。