誰が作成・修正したのか、自動的に追跡する

In the previous section we establish a method for retrieving the logged in user from anywhere in
your application. Now we can apply this to setting the created by and modified by fields for
various database records.

前の節ではアプリケーション内の任意の場所からログイン中のユーザを取得する方法を確立しています。その方法は、様々なデータベースのレコードに対して、どのユーザがレコードを作成・更新したのかをフィールドに記録するために用いることができます。

Database
データベース

First off, add the fields “created_user_id” and “modified_user_id”, both ints, to any database table
you want to track changes on.

まず最初に、変更を追跡したいデータベーステーブルに “created_user_id” および “modified_user_id” フィールドを追加してください。ともに整数型です。

Model Relations
モデルの関係

Next you need to set up a belongsTo Association for each of the fields.

次に、それぞれのフィールドに対して belongsTo 関連を設定する必要があります。

var $belongsTo = array('CreatedUser' => array('className' => 'User'),
                       'ModifiedUser' => array('className' => 'User'));

Model beforeValidate Callback
モデルのbeforeValidateコールバック

This is the point that most books would show you how to do a normal model beforeValidate
callback, while you’re thinking “What a friggin’ idiot. He calls this e-book/e-pamphlet Super
Awesome Advanced CakePHP Tips, but then doesn’t know enough to make this into a behavior.”
Then in the next section the author would make it into a behavior and you would feel mildly
foolish, but justified in believing the author should have just skipped right to the behavior method.
So I won’t insult your intelligence and skip to the right way to handle this.

この段階で大抵の本ならばモデルの普通の beforeValidate コールバックを使う方法を示すでしょう。そして読者であるあなたはこう考えるのです。「とんだ間抜けだ。この電子書籍には『超素晴らしい上級者向けCakePHP Tips』なんてタイトルを付けておきながら、ビヘイビア化することも知らないなんて」。するとすぐ次の節で著者がそれをビヘイビア化したりして、あなたはちょっとばつが悪く感じたりするわけですが、しかし「著者は[モデルのbeforeValidateを使う方法は]飛ばして、まっすぐにビヘイビアメソッド[を使う方法]へ向かうべきだった」とあなたが考えるのはもっともなのです。だから私はあなたの知性を侮ることはせず、正しい方法まで飛ばすことにしましょう。

Behavior beforeValidate Callback
ビヘイビアのBeforeValidateコールバック

First let’s deal with the created by scenario.

まずは誰が作成したのか[を追跡する場合の]シナリオから扱っていきましょう。

function beforeValidate(&$model) {

  if(empty($model->data[$model->alias]['id'])) {
   $model->data[$model->alias]['created_user_id'] = User::get('id');
  }

  return true;
}

The logic here is pretty simple. We check if the “id” field is set to determine if this is a new record
or an update. We’re making a bit of a leap here, in believing that if the id is set it will be an
update. It is certainly possible that an invalid id is passed. Cake handles this by checking if the
id exists first. You’ll usually see a query like this before an insert or update:

ここで[用いられている]ロジックはとても単純です。idフィールドに[値が]設定されているかどうか調べることで、新しいレコードなのか更新なのかを決定しています。[ただし]ここで「idが設定されていれば更新だ」と考えるのは、ちょっと論理が飛躍しています。不正なidが渡される可能性は確実に存在するのです。[実際]Cakeは、まずidが存在するかどうかを調べることでこれに対処しています。あなたはいつも次のようなクエリをinsertやupdateの前に見るでしょう。

SELECT COUNT(*) AS `count` FROM `posts` AS `Post` WHERE `Post`.`id` = 1

So there is the outside possibility that the created_user_id field may not get set this way. If you
wanted to be diligent you could move the logic to an afterSave, which is passed a $created
boolean.

だからこの方法では created_user_id フィールドが設定されない可能性が、ごくわずかですか存在します。よほど念入りに行いたいのであれば、このロジックを afterSave コールバックに移すこともできます。そこでは[新しいレコードが]作成された[ことを示す]真偽値が[引数として]渡されます。

To set the modified_user_id you use basically the same code, less the check to see if this is a
new record.

この新しいレコードか否か調べる部分を除けば、modified_user_id フィールドを設定するのにも基本的に同じコードが使用できます。

$model->data[$model->alias]['modified_user_id'] = User::get(‘id’);

The Full Behavior
ビヘイビア全体


class TrackableBehavior extends ModelBehavior {
  function beforeValidate(&$model) {
    if (empty($model->data[$model->alias]['id'])) {
      $model->data[$model->alias]['created_user_id'] = User::get('id');
    }

    $model->data[$model->alias]['modified_user_id'] = User::get('id');
    return true;
  }
}
?>

Leave a Reply