Timestampable behavior

I'm not sure that I understand correctly for what purpose Behaviors in Models are used. However I suppose, that the Timestampable behavior are using for autofilling DATETIME fields during creating or updaing a row. Like that:

$user->created_at = date('Y-m-d H:i:s');

If I understand it correctly I can remove this string (above) from controller and add this in model:

    public function initialize()
    {
        $this->addBehavior(new Timestampable(array(
            'beforeCreate' => array(
                'field' => array('created_at', 'logined_at'),
                'format' => 'Y-m-d H:i:s'
            )
        )));
    }

Also in controller:

        $user = new Users();
        $user->initialize();  // Don't forget to call it to register behavior

But I can't get this work. I just post signup form and get: created_at is required logined_at is required

Yes, here is a part of my scheme:

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL DEFAULT '',
  `nickname` varchar(32) NOT NULL,
  `password` varchar(64) NOT NULL,
  `created_at` datetime NOT NULL,
  `logined_at` datetime NOT NULL,
  `karma` tinyint(4) NOT NULL DEFAULT '0',
  `role` tinyint(1) NOT NULL DEFAULT '2',
  `is_banned` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`,`nickname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

I also tried to change this two fields to accept NULL, and it inserts, but this fields was NULL instead of current timestamp formatted to DATESTAMP...

So how to trick, or maybe I don't understand something?



95.3k

'initialize' is called automatically the first time the model is used, there is no need to call it manually.

As the column 'created_at' is marked as not null and you're assigning the value in the 'beforeCreate' event and the column needs a value, this event is not being called. You need to use 'beforeValidationOnCreate':

public function initialize()
    {
        $this->addBehavior(new Timestampable(array(
            'beforeValidationOnCreate' => array(
                'field' => 'created_at',
                'format' => 'Y-m-d H:i:s'
            )
        )));
    }

Thank you! It works perfectly!



95

But what if i wanna use db-engine created_at TIMESTAMP NOT NULL DEFAULT NOW() ? What should i add to Model to support this? By default i've got created_at is required message

To let the database handle the created_at column use skipAttributes() on the model. Example:

public function initialize()
    {
        // Ignore created_at column
        $this->skipAttributes(array('created_at'));
    }

It's also possible to ignore columns only on INSERT or UPDATE. See documentation for more.

edited Oct '19

I am on building a REST APPLICATION using the Micro App

I used the PhalconDevTools to generate Models with getter setter, doc and column map. My models inherit from an Abstract class.

And I copied the behavior Timestampable implementation exactly from documentation.

The Modelgenereator writes an initialize function in the models but this is not calling parent::initialize so it was never runnning initialize from parent class. I inserted the parent::initialize(); Now it runs definitely through the initialize. But I tried all: beforeCreate / onCreate / afterCreate it never sets the created_at column I also tried the pure format string and the function version instead. (I tried var_dump/die in the date format function but it looks like its never executed)

BTW should I use created_at as in DB or createdAt as mapped here? I tried both but it isn't working.