我对(简化)表有一个模型leads_contents_interactions
:
CREATE TABLE `leads_contents_interactions` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`lead_content_id` bigint(20) unsigned DEFAULT NULL,
`created_on` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8;
我想选择这些,除了id
,lead_content_id
和created_on
列之外,我还希望它返回一列is_new
,其中是这样的:
SELECT
id,
lead_content_id,
created_on,
IF(created_on > DATE_SUB(NOW(),INTERVAL 1 DAY), 1, 0) AS is_new
FROM leads_contents_interactions;
现在我知道我可以使用PHQL执行此操作,但理想情况下不会直接查询leads_contents_interactions
,我希望在自然查询时返回此额外列:
$leads = $user->getRelated(
'leads',
array(
'Lead.deleted_by IS NULL',
'limit'=>1000
)
);
foreach($leads as $lead) {
foreach($lead->interactions as $interaction) {
echo $interaction->id."\t".$interaction->is_new.PHP_EOL;
}
}
潜在客户模型(简化)
class Lead extends PersendlyModelAbstract {
public function initialize() {
// A lead has multiple interactions, `contents`, through the weak entity `leads_contents`
$this->hasManyToMany(
'id',
'LeadsContents',
'lead_id',
'id',
'LeadsContentsInteractions',
'lead_content_id',
array('alias' => 'interactions')
);
}
}
LeadsContents模型(简化)
class LeadsContents extends PersendlyModelAbstract {
public function initialize() {
$this->belongsTo('lead_id', 'Lead', 'id', array('alias' => 'lead'));
$this->belongsTo('content_id', 'Content', 'id', array('alias' => 'content'));
$this->hasMany('id', 'LeadsContentsInteractions', 'lead_content_id');
}
}
LeadsContentsInteractions模型(简化)
class LeadsContentsInteractions extends PersendlyModelAbstract {
public function initialize() {
$this->belongsTo('lead_content_id', 'LeadsContents', 'id', array('alias' => 'lead_content'));
}
}
答案 0 :(得分:3)
如果您想要添加表中不存在的列,但作为业务规则存在(created_on> DATE_SUB(NOW(),INTERVAL 1 DAY),1,0)那么您需要添加该规则在模型本身的afterFetch方法中:
http://docs.phalconphp.com/en/latest/reference/models.html#initializing-preparing-fetched-records
class LeadsContentsInteractions extends PersendlyModelAbstract
{
public $isNew;
public function afterFetch()
{
$this->isNew = INSERT BUSINESS LOGIC HERE
}
}
但是应该注意,如果您在记录集上使用方法toArray(),它将只使用表本身上存在的列。
答案 1 :(得分:1)
回应David Duncan所说的话:
但是应该注意,如果你然后使用方法toArray() 在记录集上,它将只使用存在于的列 表本身。
为了规避这种Phalcon限制,我创建了以下方法覆盖。
基本上,创建一个BaseModel.php并将下一个代码放在那里。
/**
* Method override.
*
* This method is inherited from Model::toArray()
* https://docs.phalconphp.com/en/3.2/api/Phalcon_Mvc_Model
*
* We override it here to circumvent a Phalcon limitation:
* https://stackoverflow.com/a/27626808/466395
*
* Basically, the limitation consists that, when one adds 'virtual fields' to a model (for example,
* by way of callback methods like afterFetch()), then using toArray() on that model only returns
* the fields in the database table but not the virtual fields.
*
* @access public
* @param array $columns As per the Model::toArray() method.
* @return array The data of the model, including any custom virtual fields.
*/
public function toArray($columns = null) {
// calls the regular toArray() method
$data = parent::toArray($columns);
// then gets the model's virtual fields, if any
$virtual_fields = [];
if (!empty($this->list_virtual_fields)) {
// iterates, to get the virtual field's name, value, and getter
foreach ($this->list_virtual_fields as $name) {
$getter_name = 'get' . \Phalcon\Text::camelize($name);
$virtual_fields[$name] = $this->{$getter_name}();
}
}
// merges the model's database data with its virtual fields
$data = array_merge($data, $virtual_fields);
return $data;
}
然后,在任何应用模型中,定义将包含在上面的方法覆盖中的虚拟字段列表。例如:
public $list_virtual_fields = [
'status_label'
];
您还应该为这些虚拟字段定义类属性,设置器和getter。举个例子:
protected $status_label;
public function getStatusLabel() {
return $this->status_label;
}
public function setStatusLabel(string $status_label) {
$this->status_label = $status_label;
return $this;
}
最后,在整个应用中设置虚拟字段的值。一个例子:
public function afterFetch() {
$this->setStatusLabel('pending');
}
请注意,我的代码使用getter和setter。如果你愿意,你可以改变它。