3

我用 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 并添加另一个元素,它不会按预期工作。为了简化使用,我添加了一些像这样的门面方法

public function addDateOfBirth($date){
    $element = new BS_VCardElement();
    $element->setName("BDAY");
    $element->addValue($date);
    // This doesn't work
    $this->elements[] = $element;
}

Docs/Storing 相关记录没有解释如何将这样的新数据附加到相关表中。

我也试过这个

$this->elements[] = array_merge($this->elements,array($element));

但是 save 方法似乎忽略了添加的元素。Save() 返回真。

4

3 回答 3

1

几个月前有人问过这个问题,但自从我遇到类似的问题后,我还是决定分享我的结果。

这就是我发现的。小写别名('elements')似乎不起作用,而大写别名('Elements')则起作用。

要添加一个元素,您可以这样做;

$this->Elements = $element;

要添加多个元素,您可以这样做;

$elements = array($element1, $element2);
$this->Elements = $elements;

之后,您必须在再次访问元素之前保存 vcard。如果不这样做,phalcon 将只返回一个结果集,其中仅包含数据库中已有的元素。(不确定这是否可以以某种方式更改。)

这是文档(所有这些都没有提到):http ://docs.phalconphp.com/en/latest/reference/models.html#storing-related-records

于 2014-06-12T09:28:41.217 回答
1

根据Phalcon 源代码,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在最后重置属性)。

我对此感到沮丧,因为将对象附加到集合似乎是一项非常常见的任务,并且没有明确的方法来向父项添加新项目似乎是一个设计缺陷。

于 2017-07-03T23:35:34.377 回答
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;
}
于 2013-08-15T20:33:58.657 回答