我在PHP中用Phalcon编写了一个vcard类。 vCard模型初始化如下。
// Inside the BS_VCard class
public function initialize(){
$this->hasMany("id","BS_VCardElement","vCardId",array(
"alias" => "elements",
'foreignKey' => array(
'action' => Phalcon\Mvc\Model\Relation::ACTION_CASCADE
)
));
}
它的元素像这样初始化
// Inside the BS_VCardElement class
public function initialize(){
$this->belongsTo("vCardId","BS_VCard","id",array("alias" => "vCard"));
...
}
如果用户读取vCard并添加其他元素,则无法按预期工作。为了简化使用,我添加了一些这样的fascade方法
public function addDateOfBirth($date){
$element = new BS_VCardElement();
$element->setName("BDAY");
$element->addValue($date);
// This doesn't work
$this->elements[] = $element;
}
Docs/Storing related records没有解释如何将这样的新数据附加到相关表格中。
我也试过这个
$this->elements[] = array_merge($this->elements,array($element));
但是save方法似乎忽略了添加的元素。 Save()返回true。
答案 0 :(得分:1)
这个问题已在几个月前被问过,但自从我遇到类似的问题后,我决定分享我的结果。
这就是我发现的。小写别名('元素')似乎不起作用,而大写别名('元素')可以。
要添加一个元素,您可以执行此操作;
$this->Elements = $element;
要添加多个元素,您可以执行此操作;
$elements = array($element1, $element2);
$this->Elements = $elements;
之后,您必须先保存vcard,然后再次访问元素。如果你不这样做,phalcon将只返回一个只包含数据库中已有元素的结果集。 (不确定这是否可以某种方式改变。)
以下是文档(未提及所有内容):http://docs.phalconphp.com/en/latest/reference/models.html#storing-related-records
答案 1 :(得分:1)
根据Phalcon source code,Resultset对象是不可移植的。
/**
* Resultsets cannot be changed. It has only been implemented to
* meet the definition of the ArrayAccess interface
*
* @param int index
* @param \Phalcon\Mvc\ModelInterface value
*/
public function offsetSet(var index, var value)
{
throw new Exception("Cursor is an immutable ArrayAccess object");
}
看来用数组替换元素是实现"追加"的唯一方法。或修改结果集(除了支持的删除)。
当然这会破坏\Phalcon\Mvc\Model::_preSaveRelatedRecords()
,因为该函数会忽略类属性并从模型管理器中重新获取相关内容(并在最后重置model::$element
属性)。
我对此感到沮丧,因为将对象附加到集合看起来像是一个非常常见的任务,并且没有一个明确的方法向父母添加新项目似乎是一个设计缺陷。
答案 2 :(得分:0)
我认为相关元素在设置属性时可能会调用一些神奇的功能,所以简单地使用$ this-> elements [](显然)不起作用。也许尝试重新设置整个变量:
public function addDateOfBirth($date){
$element = new BS_VCardElement();
$element->setName("BDAY");
$element->addValue($date);
$elements = $this->elements;
$elements[] = $element;
$this->elements = $elements;
}