ありがとう。また会おう。

ゆるいかんじで。かたのちからぬいて。やってます。

updated_at「だけ」を更新したい場合

地味だけどハマったのでメモ。


symfonyで、というより正確にはPropelで、
updated_atカラムを含むモデルを扱う場合。
この名称のカラムを作っておけば、他に特になにも設定しなくても、レコードを更新かけた時に、更新日時を自動的に保存してくれるので、便利なのですが。


今回ハマったのが、「更新日時【だけ】を更新したい」というケース。
もうちょっと正確には、別のカラムのデータも更新かけるんだけど、
それがたまたま更新前と同じデータになる時があって、
その時でも、更新日時は最新にしたいと。


具体的には、こんな感じ:

<?php
    $foo = mt_rand(1,4);
    $hoge = HogePeer::retrieveByPk(1);
    $hoge->setFoo($foo);
    $hoge->save();

1行目で、1〜4の間で乱数を取得。
そうすると、当然以前保存してた値と同じになることがあるんだけど
その場合でも更新日時だけはアップデートしたいんですわ。


ところがこの場合、Propelは、まぁ賢いっちゃあ賢いんだけど
「オブジェクトのプロパティが何も変わってないんで、UPDATE発行必要なし」と判断しちゃうようで。
更新日時が変わらない・・・というかUPDATE文自体発行しない。。。


で、どうしようかなぁ、DELETEしてINSERTしてもいいけど、なんか格好悪いしなぁ・・・と思い、Propelが生成するBaseHogeクラスのソースを眺め。
こうするのがとりあえずよさそうだ。

<?php
    $foo = mt_rand(1,4);
    $hoge = HogePeer::retrieveByPk(1);
    $hoge->setFoo($foo);
    $hoge->setUpdatedAt('now'); //明示的にupdated_atカラムを更新
    $hoge->save();

updated_atカラムを明示的にsetしたらうまくいった。
setUpdatedAt()メソッドの引数は、strtotime()関数が解釈できる文字列ならOK。


ほんとは、プロパティが変わってなくても、強制的にUPDATE文を発行させる方法がほかにあればいいんだけど、
BaseObjectクラスまで遡ってみたけど、使えそうなメソッドが見あたらなかったので、これがいいのかな。。。うん。