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?



85.4k

'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.