CakePHP-Audit-Log-Plugin
CakePHP-Audit-Log-Plugin copied to clipboard
Unable to get HABTM to work for a hasMany relationship
Hi, Rob. Thanks for your creation, this has been a great deal for me.
This is the first time I have included your plugin in a project, so please bear with me. By the way, before I talk about my problem, I must mention that I have already checked #19 and also, I have read and understood the instructions in README, esp. this:
habtmAn array of models that have a HABTM relationship with the acting model and whose changes should be monitored with the model. If the HABTM model is auditable in its own right, don't include it here. This option is for related models whose changes are only tracked relative to the acting model.
I have 2 linked models: 'Job' hasMany 'Attachment'. At present, 'Attachment' is not polymorphic but I may need to do that later to link with other models(I will come back with new issues :stuck_out_tongue_winking_eye: ). With my configuration, any and every changes to Job model are saved in the 2 DB tables perfectly. However, any addition/change on Attachment model are not recorded at all. It works if I attach the behaviour separately in latter model, but that's not what I want, I want to track linked changes. You can find my configuration for AuditLog below:
appModel
class AppModel extends Model {
public function currentUser() {
return CakeSession::read("Auth.User"); // Fix based on solution suggested in issue #35
}
}
Job
public $actsAs = array(
'Tree', // inclusion of this behavior is somewhat common here and in issue #19, but not exactly same
'AuditLog.Auditable' => array(
'ignore' => array( 'lft', 'rght', 'created_by', 'created' ),
'habtm' => array( 'Attachment' )
)
);
// No validations exist in test env so far.
// 'belongsTo' associations are not shown for the sake of brevity
// trimmed hasMany associations to show necessary code only
public $hasMany = array(
'Attachment' => array(
'className' => 'Attachment',
'foreignKey' => 'job_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
'Audit' => array( // Used to retrieve and display log
'className' => 'Audit',
'foreignKey' => 'entity_id',
'dependent' => false,
'conditions' => array(
'Audit.model' => 'Job',
),
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
AuditableBehavior is not directly called in any other model.
Apologies for such long post, I just wanted to make sure that you understand my implementation clearly.
_P.S:_
- Suggested
currentUser()and associated code in controller'sbeforeFilter()in README doesn't work. An edit in README will be great. - I hoped that
Audit hasMany AuditDeltawould be in place to support easy retrieval. On checking the behavior, I noticed the association exists inbeforeSave()which is called only before saving. While there is no provision for retrieving the log (which I agree, is reasonable due different needs of different developer), it should still be handy to have the relationship available during afind()call. For now, I usedcontainablein my controller to cover this shortcoming.
@fr0z3nfyr can you still reproduce this with the current version (dev-master)? You would help us.
On your "P.S:"
-
Should be fixed now.
-
Since merging #102 there are actual models with a relationship set between them:
https://github.com/robwilkerson/CakePHP-Audit-Log-Plugin/blob/cc1862c4217a97d69962699361261c7ec7ea7051/Model/Audit.php#L14 https://github.com/robwilkerson/CakePHP-Audit-Log-Plugin/blob/cc1862c4217a97d69962699361261c7ec7ea7051/Model/AuditDelta.php#L14
@ravage84 Thanks for your reply. i had made several changes to my code and DB structure, and am using the said model with a polymorphic behaviour. I haven't tried dev master yet but I can test it within this week and post my observation. Thanks for taking this further.
@ravage84 Sorry for late response. I tried with the latest master as of today. Couldn't get it to work for the love of lord, kept getting errors on lines 242 and 262 in AuditableBehavior.php
Fatal error: Call to a member function create() on a non-object in C:\wamp\www\plerp\app\Plugin\AuditLog\Model\Behavior\AuditableBehavior.php on line 242. Arghh. I hate Windows (My linux died on me and is out for repair, working on replacement machine), but I doubt it is specific to windows.
I didn't touch the plugin code this time. Followed the updated readme - copied/pasted respective code in AppController and AppModel. Made sure that I'm not binding Audit or AuditDelta models on the fly anywhere. Tried disabling the habtm setting as well, no use.
Surprisingly, error on line 242 popped up in the last few minutes of test. Until then it was always line 262. Even clearing cache and restarting my server didn't work.
I'm sorry, I don't see the problem. The code in 2.1.0 works in my project and the behavior should make sure the models are bound here: https://github.com/robwilkerson/CakePHP-Audit-Log-Plugin/blob/2.1.0/Model/Behavior/AuditableBehavior.php#L171-L174
Could you try to use the plugin on a vanilla/simplified app?
Hmm. Strange that it worked there! What's the version of cake? I tried on 2.6.3 (was a test instance with very few models and nothing fancy).
I got it to working by changing the behavior slightly (line 171):
// Create a runtime association with the Audit model
$Model->bindModel(
array('hasMany' => array('Audit')) // changed AuditLog.Audit to Audit
);
$Model->Audit->bindModel( // had to bind AuditDelta to Audit
array( 'hasMany' => array( 'AuditDelta' ) )
);
I wonder why it didn't work associations already in place in plugin's Audit and AuditDelta models! And what is wrong with AuditLog.Audit when binding it to $Model (this model)
P.S: The original motive of this complete trial and error - HABTM is working fine and as expected. Only thing I'd love to have in audit is the additional information in the HABTM table, for example: I have PurchaseOrder hasAndBelongsToMany Product with additional fields for count and discount. So, when I edit a PO, and change just the quantity of a product, nothing is logged (see image of my form, for reference). if I change the selected product, that is logged perfectly.
Probably, 2 additional fields in Delta table for old json and new json will be handy for this (in case of HABTM). Just my 2 cents! :smiley: