Cakephp之前在使用saveAll时不保留新数据?

时间:2011-01-24 21:56:04

标签: php cakephp callback save

我有一个相对简单的条目模型,只有五个字段:

  1. ID
  2. type(此条目的数据类型)
  3. 金额(无论何种类型)
  4. 单位(类型的单位)
  5. 日期(输入此条目的日期时间)
  6. user_id(输入用户的ID
  7. 所以,没什么特别的。现在,单个表单可以有多个条目(已经存在的条目和刚创建的新条目),表单通过ajax调用进行扩展。

    当我提交表单时,$this->data看起来像这样:

    Array
    (
        [Entry] => Array
            (
                [date] => 2011-01-07
                [0] => Array
                    (
                        [id] => 1
                        [type] => Eat
                        [amount] => 1 Steak, one baked potatoe
                        [unit] => lunch
                        [time] => Array
                            (
                                [hour] => 13
                                [min] => 31
                            )
    
                    )
    
                [1] => Array
                    (
                        [type] => weight
                        [amount] => 78.5
                        [unit] => KG
                        [time] => Array
                            (
                                [hour] => 22
                                [min] => 22
                            )
    
                    )
    
            )
    
    )
    

    $this->data['Entry']['date']中的第一个条目是所有条目应使用的日期。而且由于缺少user_id,我在entry-model中创建了一个“beforeSave”函数。它看起来像这样:

    function beforeSave() {
        App::import('Component','Session');
        $this->Session = new SessionComponent();
    
        if (isset($this->data) && isset($this->data['Entry'])) {
            $date = $this->data['Entry']['date'];
            unset($this->data['Entry']['date']);
    
            foreach ($this->data['Entry'] as $n => $entry) {
                if (is_array($entry)) {
                 $this->data['Entry'][$n]['date'] = $date . ' ' . $entry['time']['hour'] . ':' . $entry['time']['min'] . ':00';
                    $this->data['Entry'][$n]['user_id'] = $this->Session->read('Auth.User.id');
                }
            }
            debug($this->data);
    
        }
        return true;
    }
    

    我删除日期,将其与用户的时间条目一起添加,从而创建一个mysql datetime条目并添加登录用户的user_id。直截了当,真的。结果数组(由最后debug()输出)如下所示:

    Array
    (
        [Entry] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [type] => Eat
                    [amount] => 1 Steak, 1 baked potatoe
                    [unit] => lunch
                    [time] => Array
                        (
                            [hour] => 09
                            [min] => 31
                        )
    
                    [date] => 2011-01-07 09:31:00
                    [user_id] => 2
                )
    
            [1] => Array
                (
                    [type] => Weight
                    [amount] => 78.5
                    [unit] => KG
                    [time] => Array
                        (
                            [hour] => 22
                            [min] => 22
                        )
    
                    [date] => 2011-01-07 22:22:00
                    [user_id] => 2
                )
    
        )
    
    )
    

    因此它看起来与我希望它看起来完全一样,应该很容易保存。但是当我使用$this->Entry->saveAll($this->data['Entry'])保存所有条目时,它不仅不起作用,而且当我在saveAll之后直接调试$this->data时,它看起来与saveAll函数之前完全一样 - 日期又回来了在数组中,条目没有日期或user_id条目。

    我可以看到beforeSave被调用,我可以看到它更改$this->data,但是在beforeSave结束和“saveAll”的使用之间的某处,我的所有更改都会丢失并且$this->data被还原它的原始状态。因此不会进行保存。

4 个答案:

答案 0 :(得分:6)

尝试使用hasMany实现一些清理时遇到了类似的问题。事实证明问题在于saveAll()的工作原理。控制器中的$ this->数据与Model :: beforeSave()回调中的$ this->数据不同,两者不同步。当你调用Model :: saveAll()从控制器传递$ this->数据时你明确地给模型“旧版本”的数据数组。当你在cake / libs / model / model.php中查看saveAll定义时,它只会:

if (empty($data)) {
   $data = $this->data
}

并且不再需要在模型中同步修改后的$ data数组,并通过参数$ data从控制器传递。解决方案是不将数据传递给saveAll(),而是首先使用Model :: set()在模型上设置数据,然后调用Model :: saveAll()(不带$ data参数)。

答案 1 :(得分:1)

当我们调用SaveAll时,不会将更新/提交的数据传递给模型的beforeSave。从这个问题出来,

在模型中创建tmp_data数组

var $tmp_data = array();

在saveall调用之前,设置此变量, 即。

$this->model->tmp_data = $this->data;
$this->model->saveAll();

然后,修改model-> beforeSaveBefore的代码 而不是$this->data use $this->tmp_data

答案 2 :(得分:0)

据我所知saveAll()updateAll()和deleteAll()默认情况下不会触发任何回调

您需要手动启用它们(方法的最后一个参数)

答案 3 :(得分:0)

你有没有因为验证而被绊倒?

尝试

$this->Entry->saveAll($data,array('validate'=>false));

如果有效则问题在于验证

但是,如果没有指定主键,请不要忘记在保存单个模型之前需要使用create()。也许在saveAll()中混合新数据和现有数据是个问题。