LoginSignup
12
12

More than 5 years have passed since last update.

Phalcon で Timestampable ビヘイビアを使う

Last updated at Posted at 2014-06-01

created_atupdated_at を追加したい

craeted_atupdated_at など,そのレコードが作成された時や更新された時の時間を記録しておきたい場合について.

保存した後や保存する前など特定のタイミングで処理を行いたいようなものはビヘイビアで実装できる. MySQL ではデフォルト値を設定できないためアプリケーションで SQL 発行時に now() などを使うようにする必要がある.

Timestampable を使う

例えば下記のようなスキーマを使う場合について.

CREATE TABLE `post` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `message` varchar(1000) NOT NULL DEFAULT '',
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

created_at が新しく追加されたタイミング,updated_at が更新されたタイミングで 時間を更新したい場合は下記のように書く.
field が対象としたいカラムの名前( columnMap() で名前を変更している場合は連想配列の値の方),format は php の format_date() で指定できる形式の文字列を指定する.
field は対象が一つの場合は単なる文字列でいいが,複数の場合は配列で渡すとよい.

class Post extends Phalcon\Mvc\Model
{
    public function initialize()
    {
        $this->addBehavior(new Phalcon\Mvc\Model\Behavior\Timestampable(array(
            'beforeCreate' => array(
                'field' => array(
                    'created_at',
                    'updated_at'
                ),
                'format' => 'Y-m-d H:i:s'
            ),
            'beforeUpdate' => array(
                'field'  => 'updated_at',
                'format' => 'Y-m-d H:i:s'
            ),
        )));
    }
}

NOT NULL が付いている場合

例えば下記のように対象となるカラムに NOT NULL が付いている場合.

CREATE TABLE `post` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `message` varchar(1000) NOT NULL DEFAULT '',
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4;

Phalcon の Model ではカラムに NOT NULL が付いている場合,自動的に Phalcon\Mvc\Model\Validator\PresenceOf バリデーションが動く.
そのため前述のコードでは created_at is requiredupdated_at is required のようなエラーメッセージが発生する.
これを防ぐためには PresenceOf バリデーションが発生しないようにするか,バリデーション前にビヘイビアの処理が動くようにする必要がある.

PresenceOf の挙動を止める

どこかしらで下記の記述を追加する.ただしこれを追加すると他のカラムの NOT NULL の場合のバリデーションもなくなるので自身で PresenceOf バリデーションを追加する必要があるようになるはず.

\Phalcon\Mvc\Model::setup(array(    
    'notNullValidations' => false
));

バリデーション前にビヘイビアの処理を動かす

全体に影響させないようにしたい場合は,下記のようにバリデーションが動く前に Timestampable ビヘイビアの処理が動くようにしたものをつかう.
このリストの中に beforeValidation が付いたものがあるのでこれを指定する.

class Post extends Phalcon\Mvc\Model
{
    public function initialize()
    {
        $this->addBehavior(new Phalcon\Mvc\Model\Behavior\Timestampable(array(
            'beforeValidationOnCreate' => array(
                'field' => array(
                    'created_at',
                    'updated_at'
                ),
                'format' => 'Y-m-d H:i:s'
            ),
            'beforeValidationOnUpdate' => array(
                'field'  => 'updated_at',
                'format' => 'Y-m-d H:i:s'
            ),
        )));
    }
}

参考文献

ビヘイビアについて

モデルの働き — Phalcon 1.3.1 documentation

http://docs.phalconphp.com/ja/latest/reference/models.html#id27

format オプションで指定できる形式

PHP: DateTime::format - Manual

http://www.php.net/manual/ja/datetime.format.php

NOT NULL が付いた場合の挙動について

Timestampable behavior - Discussion - Phalcon Framework

http://forum.phalconphp.com/discussion/451/timestampable-behavior

モデルで発行されるイベントのリスト

Working with Models — Phalcon 1.3.0 documentation

http://docs.phalconphp.com/en/latest/reference/models.html#events-and-events-manager

NOT NULL の場合に PresenceOf で必須のバリデーションが働かないようにすることについての議論

created_at and validation - Discussion - Phalcon Framework

http://forum.phalconphp.com/discussion/283/created-at-and-validation

実際に PresenceOf を無効にする場合に設定する項目

Working with Models — Phalcon 1.3.0 documentation

http://docs.phalconphp.com/en/latest/reference/models.html#disabling-enabling-features

12
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12