我正在使用PhalconPHP,到目前为止我遇到了一些小问题。
这个框架非常好。
然而,我遇到了一个我一直无法解决的问题。这可能是一件非常简单的事情,但我一直在兜圈子,找不到任何关于这个问题的参考。
问题是,如果同时更新相关实体,则无法更新模型对象。
例如,假设我有几个模型类。
联系人:
class Contact extends 'Phalcon'Mvc'Model
{
public function initialize()
{
$this->belongsTo('email_id', 'Email', 'id', ['alias' => 'Email']);
}
}
和电子邮件:
class Email extends 'Phalcon'Mvc'Model
{
public function initialize()
{
$this->hasMany('id', 'Contact', 'email_id', ['alias' => 'Contacts']);
}
}
当我尝试创建一个新的Contact
和Email
时,以下操作有效:
$contact = new Contact();
// ... assign other fields here (i.e. name)
$email = new Email();
// ... assign other email fields here (i.e. address)
$contact->setEmail($email); // or $contact->email = $email;
$contact->save();
// record created
然而,当我尝试更新Contact
并更改Email
关系时,信息不会更新:
// Only update other fields
$contact->name = 'Some other name';
$contact->save(); // This works
// Update the related object
$contact->name = 'A new name';
$contact->setEmail($anotherValidEmail);
$contact->save(); // This doesn't work! Not even the name field is updated
我尝试使用update()
而不是save()
。
我也尝试过使用$contact->email = $newEmailObject
,但我得到了相同的结果。
有人遇到这个问题吗?我做错了什么?
我使用Mac OS X,PhalconPHP 1.2.3
我还用PhalconPHP 1.1.0 在Windows 8上测试过它
感谢您的帮助。
更新
我已经在save()之后打印了$contact->getMessage()的结果,但没有得到任何结果。就好像save()成功了,但是,没有执行SQL语句。
上次更新:已复制问题并找到解决方法
我们已经能够复制这个问题。我们正在这样做:
$contact = Contact::findFirst(123);
if ($contact->email->emailaddress != $newaddress) {
$email = new Email();
$email->emailaddress = $newaddress;
$contact->email = $email;
$contact->save();
}
这不起作用!一旦我们将与电子邮件相关的对象中的emailaddress字段与新地址的字符串进行比较,则无法保存。
然而,如果我们稍微修改一下代码并这样做:
$contact = Contact::findFirst(123);
if ($contact->email->emailaddress != $newaddress) {
$email = new Email();
$email->emailaddress = $newaddress;
// Load the record (again!)
$contact = Contact::findFirst(123);
$contact->email = $email;
$contact->save();
}
这确实有效。
我想加载相关对象会影响更新特定字段的能力,再次找到联系人对象会刷新相关对象。
因此,我们有一个变通办法,我希望能帮助其他面临同样问题的人。
使用$contact->setEmail($anotherValidEmail);
时,必须在Contact模型Contact中有一个set和get方法。例如:
Class Contact
{
public $email;
public function setEmail($email)
{
}
public function getEmail()
{
return $this->email
}
}
在官方声明中有答案,你应该试试(添加标志ACTION_CASCADE):
<?php
namespace Store'Models;
use Phalcon'Mvc'Model,
Phalcon'Mvc'Model'Relation;
class Robots extends Model
{
public $id;
public $name;
public function initialize()
{
$this->hasMany('id', 'Store''Models'Parts', 'robots_id', array(
'foreignKey' => array(
'action' => Relation::ACTION_CASCADE
)
));
}
}
http://docs.phalconphp.com/en/latest/reference/models.html#cascade-限制行动
上述代码设置为删除所有引用的记录(部分)如果主记录(robot)被删除。
您还可以使用beforeDelete或afterDelete函数并添加所需的任何代码:
http://phalcon-php-framework-documentation.readthedocs.org/en/latest/reference/models.html#deleting-记录
所有其他可用活动:http://phalcon-php-framework-documentation.readthedocs.org/en/latest/reference/models.html#events-和事件管理器
Actually, your model should look like as below
class Contact extends 'Phalcon'Mvc'Model
{
public $id;
public $name;
public $email;
public function initialize()
{
$this->belongsTo('email_id', 'Email', 'id', ['alias' => 'Email']);
}
public function columnMap()
{
return array(
'id' => 'id',
'name' => 'name',
'email' => 'email'
);
}
}
然后,
$contact=新联系人();
$success=$contact->save($this->request->getPost(),array('name','email'));