I am working with PhalconPHP and so far I have had little problems.
The framework is very good.
However, I've run into a problem that I haven't been able to sort out. It's probably a very simple thing but I've been running in circles, and couldn't find any reference to this problem.
The problem is I cannot update a model object if I also update a related entity.
For example, let's suppose I have a couple of model classes.
Contact:
class Contact extends \Phalcon\Mvc\Model
{
public function initialize()
{
$this->belongsTo('email_id', 'Email', 'id', ['alias' => 'Email']);
}
}
And Email:
class Email extends \Phalcon\Mvc\Model
{
public function initialize()
{
$this->hasMany('id', 'Contact', 'email_id', ['alias' => 'Contacts']);
}
}
When I try to create a new Contact
and Email
the following works:
$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
However, when I try to update a Contact
and change the Email
relation, the information is just not updated:
// 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
I have tried using update()
instead of save()
.
I have tried using $contact->email = $newEmailObject
as well, but I get the same results.
Have anyone ran into this problem? What am I doing wrong?
I'm using Mac OS X, PhalconPHP 1.2.3
I've also tested it on Windows 8, with PhalconPHP 1.1.0
Any help is appreciated.
updated
I have printed the results of $contact->getMessages() after save(), but I get no results. It's as if save() was successful, however, no SQL statement is executed.
LAST UPDATE: Problem replicated and Workaround found!
We have been able to replicate the problem. We are doing this:
$contact = Contact::findFirst(123);
if ($contact->email->emailaddress != $newaddress) {
$email = new Email();
$email->emailaddress = $newaddress;
$contact->email = $email;
$contact->save();
}
This DOES NOT WORK! Once we compare the emailaddress field from the email related object, to the string for the new address saving does not work.
However, if we modify the code a little bit and do this:
$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();
}
This actually works.
I guess that loading the related object affects the ability to update that particular field, and finding the contact object again, flushes the related object.
So, we have a workaround that I hope will help other people facing the same problem.
When you use $contact->setEmail($anotherValidEmail);
, you must have a set and get method in the Contact model Contact.
For example:
Class Contact
{
public $email;
public function setEmail($email)
{
}
public function getEmail()
{
return $this->email
}
}