これは、私が最初に考えたよりも簡単に答えが得られるかもしれない質問です.
あなたが今持っているものから始めましょう:
- 拡張するモデルクラス
Doctrine_Record
- 私の例では、このクラスを呼び出します
Test
。
- この
Test
モデルでは、動作を使用したいのですが、値Timestampable
ではなく UNIX タイムスタンプを使用します。datetime
- そして、モデルに多くの構成を記述する必要なく、これが必要です。
(私はそれを理解できます:どこかで1行を忘れて、DBの間違ったデータであるリスクが少なくなります)
- 構成されたプロジェクトとすべて
- これは、あなたが Doctrine を使っていることを知っていることを意味します
- 基本的なことはお話ししません
この問題の解決策Timestampable
は、Doctrine に付属するデフォルトの動作を使用するのではなく、別の動作を定義することです。
つまり、モデルでは、setTableDefinition
methodの下部に次のようなものがあります。
$this->actAs('MyTimestampable');
(私はこれもsetUp
メソッドに入ることができると思います.btw - 実際には本当の場所かもしれません)
私たちが今しなければならないことは、そのMyTimestampable
振る舞いを定義することです。
DoctrineDoctrine_Template_Timestampable
はすでにかなりうまく機能しているので(もちろん、フォーマットを除いて)、それを継承します。うまくいけば、それは書くコードが少なくなることを意味します;-)
したがって、次のように動作クラスを宣言します。
class MyTimestampable extends Doctrine_Template_Timestampable
{
// Here it will come ^^
}
Doctrine_Template_Timestampable
では、Doctrine のコード ソースで実際に何をするか見てみましょう:
- 少しの設定(2 つのフィールド
created_at
とupdated_at
フィールド)
- そして、リスナーを登録する次の行:
$this->addListener(new Doctrine_Template_Listener_Timestampable($this->_options));
このソースを見てみましょう。この部分に気付きます:
if ($options['type'] == 'date') {
return date($options['format'], time());
} else if ($options['type'] == 'timestamp') {
return date($options['format'], time());
} else {
return time();
}
これは、2 つのフィールドcreated_at
とupdated_at
フィールドの型がdate
nortimestamp
でない場合、Doctrine_Template_Listener_Timestampable
自動的に UNIX タイムスタンプを使用することを意味します。これは非常に便利です。
type
すべてのモデルでこれらのフィールドに使用するを定義したくないので、MyTimestampable
クラスを変更します。
ビヘイビアーの設定を担当するのは
extends であると言ったことを思い出してください...Doctrine_Template_Timestampable
そのため、 andtype
以外を使用して、その構成をオーバーライドします。date
timestamp
class MyTimestampable extends Doctrine_Template_Timestampable
{
protected $_options = array(
'created' => array('name' => 'created_at',
'alias' => null,
'type' => 'integer',
'disabled' => false,
'expression' => false,
'options' => array('notnull' => true)),
'updated' => array('name' => 'updated_at',
'alias' => null,
'type' => 'integer',
'disabled' => false,
'expression' => false,
'onInsert' => true,
'options' => array('notnull' => true)));
}
先に、私たちのモデルは... ではMyTimestampable
なくTimestampable
... として機能していると言いました。では、結果を見てみましょう;-)
このモデルクラスを次のように考えるとTest
:
class Test extends Doctrine_Record
{
public function setTableDefinition()
{
$this->setTableName('test');
$this->hasColumn('id', 'integer', 4, array(
'type' => 'integer',
'length' => 4,
'unsigned' => 0,
'primary' => true,
'autoincrement' => true,
));
$this->hasColumn('name', 'string', 32, array(
'type' => 'string',
'length' => 32,
'fixed' => false,
'primary' => false,
'notnull' => true,
'autoincrement' => false,
));
$this->hasColumn('value', 'string', 128, array(
'type' => 'string',
'length' => 128,
'fixed' => false,
'primary' => false,
'notnull' => true,
'autoincrement' => false,
));
$this->hasColumn('created_at', 'integer', 4, array(
'type' => 'integer',
'length' => 4,
'unsigned' => 0,
'primary' => false,
'notnull' => true,
'autoincrement' => false,
));
$this->hasColumn('updated_at', 'integer', 4, array(
'type' => 'integer',
'length' => 4,
'unsigned' => 0,
'primary' => false,
'notnull' => false,
'autoincrement' => false,
));
$this->actAs('MyTimestampable');
}
}
これは、次の MySQL テーブルにマップされます。
CREATE TABLE `test1`.`test` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(32) NOT NULL,
`value` varchar(128) NOT NULL,
`created_at` int(11) NOT NULL,
`updated_at` int(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
この方法でテーブルに 2 つの行を作成できます。
$test = new Test();
$test->name = 'Test 1';
$test->value = 'My Value 2';
$test->save();
$test = new Test();
$test->name = 'Test 2';
$test->value = 'My Value 2';
$test->save();
DB の値を確認すると、次のような結果が得られます。
mysql> select * from test;
+----+--------+----------------+------------+------------+
| id | name | value | created_at | updated_at |
+----+--------+----------------+------------+------------+
| 1 | Test 1 | My Value 1 | 1248805507 | 1248805507 |
| 2 | Test 2 | My Value 2 | 1248805583 | 1248805583 |
+----+--------+----------------+------------+------------+
2 rows in set (0.00 sec)
したがって、行の作成は問題ないようです ;-)
それでは、2 行目をフェッチして更新しましょう。
$test = Doctrine::getTable('Test')->find(2);
$test->value = 'My New Value 2';
$test->save();
DB に戻ると、次のようになります。
mysql> select * from test;
+----+--------+----------------+------------+------------+
| id | name | value | created_at | updated_at |
+----+--------+----------------+------------+------------+
| 1 | Test 1 | My Value 1 | 1248805507 | 1248805507 |
| 2 | Test 2 | My New Value 2 | 1248805583 | 1248805821 |
+----+--------+----------------+------------+------------+
2 rows in set (0.00 sec)
updated_at
フィールドが更新され、フィールドcreated_at
は変更されていません。これもOKのようです;-)
したがって、物事を短くするために、いくつかの箇条書きに収まるようにし、かなり要約します:
- 私たちのモデルクラス
MyTimestampable
は、デフォルトではなく、独自の として機能しますTimestampable
- 私たちの行動はDoctrineの行動を拡張します
- そして、その構成をオーバーライドするだけです
- したがって、モデルごとに 1 行のコードだけで、必要に応じて使用できます。
より集中的なテストをいくつか実施させていただきますが、これがお役に立てば幸いです。
楽しんでください:-)