简体   繁体   中英

Yii many to many to many filter

I'm relatively new to SQL and even newer to the joys of Yii CDbCriteria. Here's what I'm trying to do:

I have four different classes

  • Products
  • Category
  • ProductHasCategory
  • ProductLocalization

Products and Category are linked by a many to many relationship (represented by the ProductHasCategory object). A product can have multiple ProductLocalization.

类表示

Here's the scenario: a visitor lands on the view action of a CategoryController. The category has a locale identifier (for example 'en').

I'd like to be able to retrieve the Products available for that category (easy so far), but only the one with a 'en' localization.

I've been able to accomplish that using extremely inefficient ways (eg. for loops*). What would be the best way to accomplish this in the real world?

*Edit: By request, here's the (naive) solution I found so far:

$productWithAppropriateLocalization = array();
foreach ($category->products as $product){

            $locale_product = ProductLocalization::model()->find("product_id = :product_id AND locale = :locale", array(":product_id"=>$product->id, ":locale"=>$category->locale));
            $productWithAppropriateLocalization[] = $locale_product;

        }

$localizedProductsDataProvider = CArrayDataProvider($productWithAppropriateLocalization);

Obviously, this is neither elegant nor optimal; unless I heavily cache the result.

Mmm something like this?

$params['someLocale'] = 'en';
$params['someCategoryId'] = 11;
$params['someId'] = 3; //This is obviously an example, set $params to whatever you need
$condition = 't.Product_id=:someId AND t.locale=:someLocale AND Product.ProductHasCategory.Category.id =:someCategoryId';
$productLocalization = ProductLocalization::model()->with('Product','Product.ProductHasCategory','Product.ProductHasCategory.Category')->find(array('condition'=>$condition, 'params'=>$params));

I'm not 100% sure about the way I'm addressing the category relationship in the condition, but if anything let me know

You can then get the related model with...

$product = $productLocalization->getRelated('Product')->getAttributes();

Please note I don't know the names of your relations, I'd need to look at your model files in order to get that right, but I think it should be something similar to that.

Sounds like what you are after is a parameterized scope on the Localization model.

I would start by making sure you can pull just localizations for 'en' from the product model and work your way back from there. You'll probably need:

  • a parameterized scope in your product localization model
  • a parameterized scope in your product model (that scopes your product -> localization model)
  • use of the above scope with a parameter from your category model

Details are at the bottom of this section: http://www.yiiframework.com/doc/guide/1.1/en/database.arr#relational-query-with-named-scopes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM