We are moving our forum in GitHub Discussions. For questions about Phalcon v3/v4 you can visit here and for Phalcon v5 here.

Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

ORM afterFetch and beforeSave

Hi,

I'm actually using afterFetch and beforeSave to set transformation logic on the models and I didn't realize until now that if I create a Model instance and save it the instance retains the beforeSave transformations. For example:

// a model wich receives a datetime object and before save transforms it to datetime string
class Example extends Model 
{
      public function afterFetch()
      {
            $this->start = new DateTime($this->start);
      }

      public function beforeSave()
      {
          $this->start = $this->start->format("Y-m-d H:i:s");
      }
}

so, when I fetch the model I get $instance->start = Datetime object

and for saving:

   $example = new Example();
   $example->start = new DateTime();
   $example->save();  

   var_dump($example); // $example->start is now a string (used to save in database)

it saves correctly on database but I can't use the object properly since the data integrity fail.

So the question is: How can achieve this? Not using setters and getters manually.

P.D. I already wrote about this on other post etc, but it will be great to have magic getters and setters used when defined.

class Example extends Model 
{
      public function setStart(DateTime $start)
      {
            $this->start = $this->start->format("Y-m-d H:i:s");
      }

      public function getStart()
      {
          return new DateTime($this->start);
      }
}

There is another event called beforeValidationOnUpdate. Put the logic you currently have in beforeSave() in beforeValidationOnUpdate(), and the $start value will be converted to a string before it gets validated.

There is another event called beforeValidationOnUpdate. Put the logic you currently have in beforeSave() in beforeValidationOnUpdate(), and the $start value will be converted to a string before it gets validated.

This does not work of course. What beforeValidationOnUpdate would do is the same I do but before validate the data and only on update. What I want is to have a model with some properties filled with objects (don't need to know the specific database format, like dates for example) and everytime I access that properties I want to have the objects I set. Actually, when I save, the model itself transforms the data to match the database needs, but after that (the saving) my model kepts the data transformed (on the example the property becomes a string beforeSave and after that).



125.5k
Accepted
answer

Look at the afterSave() event then. In beforeValidationOnUpdate(), you store the object that is in $start in some other class variable - something like $_startWhileSaving. Then convert $start to a string. In afterSave(), you then transfer the value of $_startWhileSaving back in to $start

Look at the afterSave() event then. In beforeValidationOnUpdate(), you store the object that is in $start in some other class variable - something like $_startWhileSaving. Then convert $start to a string. In afterSave(), you then transfer the value of $_startWhileSaving back in to $start

Yes, that could do the trick. I was so focus in getter and setters that I didn't realize about the afterSave. I will try it asap. Thanks.