Если ваша ассоциация содержит дополнительные данные, вы можете объявить себя классом Purchase
и добавить следующие отношения:
class User extends CActiveRecord
{
public function relations()
{
return array(
'purchases' => array(self::HAS_MANY, 'Purchase', 'user_id'),
// Products purchased by this user
'products' => array(
self::HAS_MANY, 'Product', 'product_id',
'through' => 'purchases',
),
);
}
}
class Purchase extends CActiveRecord
{
// You need to add this, since every purchase is uniquely identified
// by user and product. Surrogate 'id' key is also fine
public function primaryKey()
{
return array('user_id', 'product_id');
}
public function relations()
{
return array(
'user' => array(self::BELONGS_TO, 'User', 'user_id'),
'product' => array(self::BELONGS_TO, 'Product', 'product_id'),
);
}
}
Удалить оставшиеся отношения MANY_MANY
из моделей User
и Product
.Обратите внимание на использование отношений от до .Выборка данных может выглядеть следующим образом:
$users = User::model()->with('purchases.product')->findAll();
foreach ($users as $user) {
echo $user->username . "<br>";
echo 'Purchases<br>';
foreach ($user->purchases as $purchase) {
echo "Date: {$purchase->purchased_at}<br>";
echo "Product: {$purchase->product->name} <br>";
}
echo '<hr>';
}
Это выполнит только один запрос из таблицы User
, соединяющей две другие таблицы.Также User::model()->with('products')
будет эффективно находить пользователей с продуктами, которые они купили.Ваша схема БД может оставаться прежней, за исключением того, что вам потребуется добавить составной первичный ключ в таблицу ассоциации.
См. эту статью в вики Yii для подробного объяснения.