我有以下型号:
class Useragent extends AppModel {
public $validate = array(
'useragent' => array(
'unique' => array(
'rule' => 'isUnique',
),
)
);
public $hasMany = array(
'LoggedActions'
);
}
和
class LoggedAction extends AppModel {
public $belongsTo = array(
'Useragent' => array(
'className' => 'Useragent',
)
}
}
这两个模型的目的是跟踪网站访问者的IP地址和用户代理。我希望表格被规范化,因为我不希望每一行都重复长用户代理字符串。
要跟踪访问者,代码如下:
$data=array(
'LoggedAction'=>array(
'ip_address' => 3232235521, //INET_ATON format
),
'Useragent'=>array(
'useragent'=>'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'
)
);
$this->LoggedAction->saveAssociated($data);
如果用户代理已存在于Useragent
表格中(仅基于字段useragents
,我希望Useragent.useragent
模型忽略保存,不在执行保存时未知的Useragent.id
上。
我知道我可以在控制器上实现这一点,首先处理Useragent
然后再处理LoggedAction
。但是,我希望模型能够透明地处理这个问题。
Useragent::beforeSave()
中返回false不起作用,因为没有保存。Useragent['id']
替换Useragent::beforeSave()
中的id
将不会进行验证。删除验证规则将抛出Integrity constraint violation: 1062 Duplicate entry '1' for key 'PRIMARY'
。选项是覆盖Useragent::save()
方法,以便忽略保存操作,但将Useragent->id
设置为提取的记录的id
从db返回数组(就像普通的保存一样),但不确定这是否会破坏其他功能。
另一种选择是编写一个名为LoggedAction::saveWithUseragent()
的方法,它将实现所描述的功能。但正如我所说,我希望模型Useragent
尽可能透明地处理这个问题。
有没有更好的实现方法,我错过了?
答案 0 :(得分:0)
我最终选择覆盖Useragent::save()
。
这就是我的Useragent
课程现在的样子:
class Useragent extends AppModel
{
public $displayField = 'useragent';
public $hasMany = array(
'LoggedActions'
);
public function save($data = null, $validate = true, $fieldList = array()){
if ($useragent=$this->findByUseragent($data['useragent'])){
$this->id=$useragent[$this->alias]['id'];
return($useragent);
}
return parent::save($data,$validate,$fieldList);
}
}
到目前为止没有问题。
可以将相同的方法用于与其他模型相关联的标签。