如何在Magento Collection中添加动态字段?
-
16-10-2019 - |
题
我创建了一个这样的洋红色集合来计算与LAT长的距离。
$collection = Mage::getModel('module/module')->getCollection()->addFieldToFilter('status',1);
$collection->getSelect()->columns(array('distance' => new Zend_Db_Expr("( 6371 * acos( cos( radians(23.0130648) ) * cos( radians( latitude ) ) * cos( radians( longitude) - radians(72.4909026) ) + sin( radians(23.0130648) ) * sin( radians( latitude ) ) ) )")))
->having('distance <10')
->order('distance ' . Varien_Db_Select::SQL_ASC);
但是我会发现错误SQLSTATE [42S22]:找不到列:1054未知列“距离”中的“ avate oble”。
当我打印收集对象距离时,计算正确。那是什么问题?
我的问题类似于这个问题 在Magento Collection中使用“ Have”的问题
我正在使用分页收集,如果我删除了分页课,那么它可以很好地完成。但是我无法用提供的解决方案解决。这是我的分页代码。
在 _prepareLayout()
我把这个功能
$pager = $this->getLayout()->createBlock('page/html_pager', 'pager');
$pager->setAvailableLimit(array(5=>5,10=>10,20=>20,'all'=>'all'));
$pager->setCollection($this->getCollection());
$this->setChild('pager', $pager);
$this->getCollection()->load();
return $this;
还将此功能添加到块文件中
public function getPagerHtml()
{
return $this->getChildHtml('pager');
}
并在phtml文件中称此为 <?php echo $this->getPagerHtml(); ?>
解决方案
我可以尝试使用 addExpressionFieldToSelect
.
您可以在 Mage_Core_Model_Resource_Db_Collection_Abstract
.
就您而言,应该是这样的:(这只是一个假设,您可能会遇到一些错误,但是这个想法还可以)
$collection = Mage::getModel('module/module')->getCollection()->addFieldToFilter('status',1);
$collection->addExpressionFieldToSelect('distance', '( 6371 * acos( cos( radians(23.0130648) ) * cos( radians( {{latitude}}) ) * cos( radians( {{longitude}}) - radians(72.4909026) ) + sin( radians(23.0130648) ) * sin( radians( {{latitude}}) ) ) )', array('latitude'=>'latitude', 'longitude'=>'longitude'));
$collection->getSelect()->having('distance > 10');
这 addExpressionFieldToSelect
这样的工作:
第一个参数是表达式的别名(虚拟字段名称)。
第二个参数是表达式。用占位符包裹的arround替换字段名称 {{...}}
第三个参数是占位符信函(没有 {{}}
)。就你而言 latitide
占位符对应 latitude
字段如此 {{latitude}}
将被取代 latitude
. 。也是如此 longitude
.
编辑
在添加分页时存在问题 $collection
像这样
$collection->setCurPage(1)->setPageSize(5);
这是问题的回溯。加载集合时称为 _renderLimit()
. 。该方法看起来像这样
protected function _renderLimit()
{
if($this->_pageSize){
$this->_select->limitPage($this->getCurPage(), $this->_pageSize);
}
return $this;
}
所以这要打电话 getCurPage()
(看 Varien_Data_Collection
班级)。
getCurPage
还有一个额外的验证来查看页码是否不超出最大范围,因此它计算出页面的总数 getLastPageNumber()
.
这里的问题是,Magento重置SELECT中的列以计算收集大小。在 Varien_Data_Collection_Db::getSelectCountSql
有这样的:
$countSelect->reset(Zend_Db_Select::COLUMNS);
通过重置列最终使用此SQL
SELECT COUNT(*) FROM `table_name_here` AS `main_table` HAVING (distance < 10)
这就是生成错误的原因。
我在这里看到2个选项。
您覆盖了收集课程的方法
getSelectCountSql
并删除列重置:public function getSelectCountSql() { $this->_renderFilters(); $countSelect = clone $this->getSelect(); $countSelect->reset(Zend_Db_Select::ORDER); $countSelect->reset(Zend_Db_Select::LIMIT_COUNT); $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET); //$countSelect->reset(Zend_Db_Select::COLUMNS);//comment this line $countSelect->columns('COUNT(*)'); return $countSelect; }
你覆盖了
getCurPage()
跳过范围验证的方法:public function getCurPage($displacement = 0){ if (!empty($this->_curPage)){ return $this->_curPage + $displacement; } return 1; }
编辑到编辑
为了避免影响其余模块,您可以覆盖 getCurPage
这样的方法:
public function getCurPage($displacement = 0){
if (!$this->getDirectCurPage()){//if a specific flag is not set behave as default
return parent::getCurPage($displacement);
}
if (!empty($this->_curPage)){
return $this->_curPage + $displacement;
}
return 1;
}
现在,当您想使用您的 having
方法只需将其添加到您的集合中
$collection->setDirectCurPage(1);
其他提示
尝试使用此方法:
$collection = Mage::getModel('module/module')->getCollection()->addFieldToFilter('status',1);
$collection->getSelect()->columns(array('distance' => new Zend_Db_Expr("( 6371 * acos( cos( radians(23.0130648) ) * cos( radians( latitude ) ) * cos( radians( longitude) - radians(72.4909026) ) + sin( radians(23.0130648) ) * sin( radians( latitude ) ) ) )")))
->addAttributeHaving('distance <10')
->addAttributeToSort('distance', Varien_Db_Select::SQL_ASC);
你可以尝试 where()
代替 having()
因为您不使用任何 JOIN
语句:
$collection->getSelect()->where('distance > ?', 10);