RSS

Neil Crookes

Learnings and Teachings on Web Application Development & CakePHP

Sep

12

Recording created_by and modified_by

One example of how you can record created_by and modified_by data in your CakePHP applications.

Share and Enjoy:

  • Digg
  • del.icio.us
  • StumbleUpon
  • Technorati
  • Slashdot

This is just a quick post to show one way of recording who created and who last modified records in your db tables.

For each table you want to record this data for:

1) Add fields called ‘created_by’ and ‘modified_by’ to your database table structure.

2) Then in your models, add the relevant belongsTo associations:


var $belongsTo = array(
'CreatedBy' => array('className' => 'User', 'foreignKey' => 'created_by'),
'ModifiedBy' => array('className' => 'User', 'foreignKey' => 'modified_by'),
);

Replace ‘User’ with whatever your ‘User’ model is called, if not ‘User’.

Then, in your AppController’s beforeFilter, which is executed before every controller action in you application, you set a property of the default model loaded by the controller that you’re in:


function beforeFilter() {
/**
* If logged in, set the model property userId to logged in user's ID
**/
if ($userId = $this->Auth->user('id')) {
$this->{$this->modelClass}->userId = $userId;
}
}

e.g. lets say you’re in your PostsController’s add action, your AppController beforeFilter will know that $this->modelClass is actually the Post model.

This code assumes you’re using CakePHP 1.2’s Auth component, if not, replace this with some similar logic from your own authentication/authorisation system that will check a user is logged in and get their ID.

And finally, in your AppModel…


var $userId = null;
function beforeSave() {
parent::beforeSave();
/**
* If logged in, set the model data created_by & modified_by fields to logged in user's ID
**/
if ($this->userId) {
$this->set(array('modified_by' => $this->userId));
/**
* Add created_by field if creating a record
**/
if (!isset($this->data[$this->name]['id']) || !$this->id) {
$this->set(array('created_by' => $this->userId));
}
}
return true;
}

This code checks to see if the model’s userId property is set, and if so, set the model’s data property modified_by field key to the userId, and if the record has not yet been created, the created_by field key too.

Don’t forget to return true at the end, else saving will fail.

Thats it, CakePHP’s Model::save() does the rest.

Something like that anyway. You might want to wrap it up in a behavior.

Share and Enjoy:

  • Digg
  • del.icio.us
  • StumbleUpon
  • Technorati
  • Slashdot
(1 votes, average: 5.00 out of 5)
Loading ... Loading ...

6 Responses so far

Awesome, thanks!!

[...] Neil Crookes » Recording created_by and modified_by [...]

It’s a nice approach.
I’ve achieved the same with a behavior – name OwnableBehavior – with an easy implementation independent of the controller. It can be done either looking on $_SESSION or implementing something similar with the auth system suggested in many posts of debbugable.com – with an static class to grab user information anywhere in the app.
Felix have used the User model in his approach, I instead preferred to create a proper class, named AppUser, and just to manage logged in user info, the AuthComponent remained doing it’s job

@rafaelbandeira3, welcome and thanks for your comment. Regarding Felix’s method, it feels weird to access stuff statically that depend on user interaction with the site? I think I prefer your method. I am either going to wrap this functionality up in a behaviour for my next project or I might check out phishy’s versionable behaviour, that looks pretty useful.

just another thought on the relation you stablished, wouldn’t it be more friendly and logical if it was: Stuff belongsTo Creator and Stuff belongsTo Editor?
I think that singular nouns are always the best approach for a relationship, as it makes much more sense on the code:
$this->Project->Milestone->find(‘all’);
$this->Task->Creator->read();

Neil, thank you for the code! This was exactly was I was looking for. Did you ever write this into a Behavior class?

Thanks again, Jeff

Leave a comment