开发者

CakePHP belongsTo relationship with a variable 'model' field

开发者 https://www.devze.com 2022-12-22 11:30 出处:网络
I\'ve got a problem with a belongsTo relationship in CakePHP. I\'ve got an \"Action\" model that uses the \"actions\" table and belongs to one of two other models, either \"Transaction\" or \"Tag\".

I've got a problem with a belongsTo relationship in CakePHP.

I've got an "Action" model that uses the "actions" table and belongs to one of two other models, either "Transaction" or "Tag". The idea being that whenever a user completes a transaction or adds a tag, the action model is create开发者_开发技巧d to keep a log of it. I've got that part working, whenever a Transaction or Tag is saved, the aftersave() method also adds an Action record. The problem comes when I try to do a find('all') on the Action model, the related Transaction or Tag record is not being returned.

actions:

id
model
model_id
created

I thought I could use the "conditions" parameter in the belongsTo relationship like this:

<?php
class Action extends AppModel {

var $name = 'Action';
var $actsAs = array('Containable');
var $belongsTo = array(
    'Transaction' => array(
        'foreignKey' => 'model_id',
        'conditions' => array("Action.model"=>"Transaction")
    ),
    'User' => array(
        'fields' => array('User.username') 
    ),
    'Recommendation' => array(
        'conditions' => array("Action.model"=>"Recommendation"),
        'foreignKey' => 'model_id'
    )
);  
}
?>

But that doesn't work.

Am I missing something here, are my relationships wrong (I suspect so)? After Googling this problem I cam across something called Polymorphic Behaviour but I'm not sure this will help me.


If I understand correctly, it sounds like the Polymorphic Behavior is a great answer. It allows you to tie a give Action record to any other model (in your case, a Transaction or Tag). If you then retrieve an Action--and memory serves (I've only used this once)--then the associated model will come back too (assuming the appropriate recursive setting).

As an example, in a recent project I built an Alert model. Alerts could be attached to any model. Any given alert record identified which model it belonged to and the appropriate record ID:

class Alert extends AppModel {
  public $actsAs    = array (
    'Polymorphic' => array (
      'classField' => 'model',
      'foreignKey' => 'entity_id'
    )
  );

  # Additional model code
}

And my table was built to the following spec:

CREATE TABLE alerts (
  id CHAR(36) NOT NULL,
  alert_template_id VARCHAR(255) NOT NULL,
  model VARCHAR(255) NOT NULL,
  entity_id CHAR(36) NOT NULL,
  valid_from BIGINT NULL,
  valid_to BIGINT NULL,
  replacement_keys TEXT NULL,
  active BOOL NOT NULL DEFAULT 0,
  created BIGINT NOT NULL,
  updated BIGINT NOT NULL,
  PRIMARY KEY(id),
  FOREIGN KEY(alert_template_id)
    REFERENCES alert_templates(id)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION
)TYPE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

Note the entity_id and model fields. For each Alert record, these hold a unique identifier and model name (e.g. User), respectively. It sounds like this would meet your needs nicely.


So if I'm correct you want to save data automatically to the Actions table? Maybe other users will give the answer that it is possible, but as far as I know this isn't.

Maybe it's a good idea to look at the model callback 'afterSave()'. Here you can do a save() after the other query is done.

0

精彩评论

暂无评论...
验证码 换一张
取 消