Cakephp - 无法在KeyValue Behavior :: beforeSave中设置Model-> id

时间:2014-09-22 14:23:39

标签: php mysql cakephp

我正在尝试实施基于https://github.com/josegonzalez/cakephp-keyvalue

的键/值行为

我的行为将为表单提交中的每个新密钥在数据库中插入新行,而不管密钥数量如何,如果在KeyValue表中找到user_id和key,则更新现有记录。我已经将用户模型与KeyValue模型以及行为联系起来。

当数据库没有user_id / key的记录时,它将正确插入新记录。但是我发现,如果我尝试更新同一用户的现有键值对,前两个值将正确更新,但提交的最后一个值将产生新记录。

经过一些调查后,我发现在beforeSave()的保存循环中,即使我在beforeSave()中使用$Model->id为模型分配ID,然后返回true,也不会传递到Model->save()班。

我正在使用cake 2.5.4

beforeSave中的

Model->id未传递到Model->save()中的lib/Model/Model.php:# 1841

if ($count > 0) {
        $cache = $this->_prepareUpdateFields(array_combine($fields, $values));

        **pr($this->id); //this value is empty**

        if (!empty($this->id)) {
            $this->__safeUpdateMode = true;
            try {
                $success = (bool)$db->update($this, $fields, $values);
            } catch (Exception $e) {
                $this->__safeUpdateMode = false;
                throw $e;
            }
            $this->__safeUpdateMode = false;
        }

KeyValueBehavior:

public function beforeSave(Model $Model, $options = array()) {
    extract($this->options[$Model->alias]);
    $keys = array_keys($Model->data[$Model->alias]);
    $data = $Model->data;

    if (in_array($fields['key'], $keys) && in_array($fields['value'], $keys)) {
        return true;
    }

    if (isset($data[$Model->alias]) && ! empty($data[$Model->alias])) {
        $dataTemplate = array($Model->alias => array());

        foreach ($data[$Model->alias] as $field => $value) {
            if ($Model->hasField($field)) {
                $dataTemplate[$Model->alias][$field] = $value;
                unset($data[$Model->alias][$field]);
            }
        }

        $index = 0;

        foreach ($data[$Model->alias] as $key => $value) {
            $index ++;
            $insert = $dataTemplate;
            $insert[$Model->alias][$fields['key']] = $key;

            if ($uniqueKeys) {
                $Model->deleteAll(reset($insert));
            }

            $insert[$Model->alias][$fields['value']] = $value;

            //check existing key value      
            $belongsTo = reset($Model->belongsTo);                      
            $existing = $Model->find('first', array(
                'conditions' => array(
                     $belongsTo['foreignKey'] => $insert[$Model->alias][$belongsTo['foreignKey']],
                     $fields['key'] => $insert[$Model->alias][$fields['key']]
                )
            ));



            $Model->create();               
            if(sizeof($existing) > 0){                  
                $existingKV = reset($existing);
                //pr($existingKV);
                $Model->read(null, $existingKV['id']);
            }


            if ($index == count($data[$Model->alias])) {
                // Even if Model->id is set here, it will not be passed to Model->save()
                $Model->id = $existingKV['id'];
                $Model->data = $insert;
                pr($Model); // Model->id is set here but not in Model->save()
                return true;
            } else {
                pr($insert); //Updates correctly
                if (false === $Model->save($insert)) {                  
                    return false;
                }
            }

        }
    }

UsersController:

public function test() {
    if ($this->request->is('post')) {
        $this->Userdetail->create();
        $this->request->data['Userdetail']['user_id'] = $this->Auth->user('id');
        if ($this->Userdetail->save($this->request->data)) {
            $this->Session->setFlash(__('The Userdetail has been saved'));
          //  $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('The Userdetail could not be saved. Please, try again.'));
        }
    }
   $users = $this->Userdetail->User->find('list');
   $this->set(compact('users'));
}

然后我在View View / Users / test.ctp中有三个示例字段:

<?php
echo $this->Form->create('Userdetail');
echo $this->Form->input('field1');
echo $this->Form->input('field2');
echo $this->Form->input('field3');
echo $this->Form->end('submit');

要解决此问题,我在beforeSave()的模型中添加了另一个名为“id_holder”的键,并编辑了Model/Model.php。但最终我不想编辑CakePHP核心。

修改:使用新的saveKeyValues()方法:

public function saveKeyValues(Model $Model, $data){
    if($Model == null || $data == null){
        return false;
    }

    if (isset($data[$Model->alias]) && ! empty($data[$Model->alias])) {
        $dataTemplate = array($Model->alias => array());
        foreach ($data[$Model->alias] as $field => $value) {
            if ($Model->hasField($field)) {
                $dataTemplate[$Model->alias][$field] = $value;
                unset($data[$Model->alias][$field]);
            }
        }
    }

    $belongsTo = reset($Model->belongsTo);
    $index = 0;

    foreach ($data[$Model->alias] as $key => $value) {
        $index++;

        $insert = $dataTemplate;
        $insert[$Model->alias][$this->options[$Model->alias]['fields']['key']] = $key;
        $insert[$Model->alias][$this->options[$Model->alias]['fields']['value']] = $value;
        $insert[$Model->alias][$belongsTo['foreignKey']] = $data[$belongsTo['foreignKey']];
        //check existing key value
        $existing = $Model->find('first', array(
            'conditions' => array(
                $belongsTo['foreignKey'] => $data[$belongsTo['foreignKey']],
                $this->options[$Model->alias]['fields']['key'] => $key
            )
        ));

        //Reset for create/update
        $Model->create();
        if(sizeof($existing) > 0){
            $existingKV = reset($existing);
            $Model->read(null, $existingKV['id']);
        }

        if (false === $Model->save($insert)) {
            return false;

        }
        if($index == count($data[$Model->alias])){
            return true;
        }
    }
}

0 个答案:

没有答案