【问题标题】:CakePHP 2.X: Prevent saveAssociated() from creating a record if it already existsCakePHP 2.X:如果 saveAssociated() 已经存在,则阻止它创建记录
【发布时间】:2015-11-27 11:30:51
【问题描述】:

我有以下型号:

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);

如果用户代理已经存在于useragents 表中,我希望Useragent 模型忽略保存(仅基于字段Useragent.useragent,而不是基于Useragent.id执行保存时未知)。

我知道我可以在控制器上实现这一点,首先处理Useragent,然后处理LoggedAction。但是,我希望模型能够透明地处理这一点。

  • 如果记录存在,则在 Useragent::beforeSave() 中返回 false 不起作用,因为没有保存任何内容。
  • 将Useragent::beforeSave() 中的Useragent['id'] 替换为从数据库中获取的现有记录中的id,将无法验证。删除验证规则将抛出 Integrity constraint violation: 1062 Duplicate entry '1' for key 'PRIMARY'。

一个选项是覆盖Useragent::save()方法,这样它会忽略保存操作,但将Useragent->id设置为从数据库中获取的记录的id并返回数组(就像普通保存一样),但不确定这是否会破坏其他功能。

另一种选择是编写一个名为LoggedAction::saveWithUseragent() 之类的方法,它将实现所描述的功能。但正如我所说,我希望模型Useragent 尽可能透明地处理这个问题。

有没有更好的方法来实现我所缺少的?

【问题讨论】:

    标签: cakephp cakephp-2.7 cakephp-2.x


    【解决方案1】:

    我最终选择了覆盖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);
        }
    }
    

    目前没有问题。

    同样的方法可以用于与其他模型关联的标签。

    【讨论】:

      猜你喜欢
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-09
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多