在我的Product
模型中,我有以下两种方法; getOrderFeedback()
是正常关系,返回ActiveQuery
和getTotalAndAveFeedback()
,返回给定Product
条记录的汇总数据数组。
/**
* @return \yii\db\ActiveQuery
*/
public function getOrderFeedback()
{
return $this->hasMany(OrderFeedback::className(), ['productID' => 'ID']);
}
/**
* @return array
*/
public function getTotalAndAveFeedback()
{
return $this->getOrderFeedback()
->select(['COUNT(*) AS num',
'AVG(rating) AS avg',
'FLOOR(AVG(rating)) AS full',
'MOD(AVG(rating), 1) AS decimal_portion',
'5 - FLOOR(AVG(rating)) - CEILING(MOD(AVG(rating),1)) AS empty'])->one();
}
当我有一组Product
并迭代它们以收集单totalAndAveFeedback
的{{1}}时,Product
会被触发,从而导致从数据库。类似于以下内容
ActiveQuery
有没有办法将$my_products = Product::find()->with(['supplier', 'location'])
->where(['published' => 1])
->all();
# SELECT * FROM product WHERE published = 1;
# Find all products
# SELECT * FROM supplier WHERE ID IN (s1, s2, s3);
# Eagerly load supplier
# SELECT * FROM location WHERE ID IN (l1, l2, l3, l4);
# Eagerly load location
foreach ($my_products as $product) {
echo $product->supplier->supplier_name;
# supplier object available from eager loading
echo $product->location->title;
# location object available from eager loading
echo $product->totalAndAveFeedback->decimal_portion;
# requires db access to 'lazy load' data for each product record
# SELECT COUNT(*) AS num, AVG(rating) AS avg, FLOOR(AVG(rating)) AS full, MOD(AVG(rating), 1) AS decimal_portion, 5 - FLOOR(AVG(rating)) - CEILING(MOD(AVG(rating),1)) AS empty FROM `order_feedback` WHERE `productID`=pID
}
视为关系,以便在getTotalAndAveFeedback()
joinWith()
上允许with()
/ Product
,以便可以急切地加载数据每个ActiveQuery
的可用方式与Product
或Supplier
关系相同吗?
我已尝试删除Location
中对one()
的调用,以允许将该方法视为关系,但getTotalAndAveFeedback()
记录的totalAndAveFeedback
属性为所有空数组,我期望一个对象具有Product
等属性,好像我调用了一个简单的关系,如decimal_portion
。
这可能在Yii2吗?
答案 0 :(得分:0)
/**
* @return \yii\db\ActiveQuery
*/
public function getTotalAndAveFeedback()
{
return $this->getOrderFeedback()
->select(['productID', 'COUNT(*) AS num',
'AVG(rating) AS avg',
'FLOOR(AVG(rating)) AS full',
'MOD(AVG(rating), 1) AS decimal_portion',
'5 - FLOOR(AVG(rating)) - CEILING(MOD(AVG(rating),1)) AS empty'])
->groupBy(['productID']);
}
正如@ Pa3Py6aka指出的那样,加入关系时数组为空的原因是没有选择productID
,返回的OrderFeedback
和Product
之间没有链接。
通过将groupBy(['productID'])
方法调用添加到ActiveQuery
,每个OrderFeedbacks
都会热切地加载并可供各个Product
对象访问。