在CakePHP中保存一个模型的多个记录

时间:2010-11-23 20:13:02

标签: cakephp save cakephp-1.3

我想为一个模型保存几条记录。如果没有出现问题,可以使用saveAll()轻松完成此操作:

我有一个通知表单,我从<select>和两个字段中选择多个用户,分别为主题和内容。现在,当我输出$this->data包含的内容时,我有:

Array([Notification] => Array
    (
        [user_id] => Array
            (
                [0] => 4
                [1] => 6
            )

        [subject] => subject
        [content] => the-content-here
    )
)

我读过Cake 1.3一书,为了保存模型的多个记录,你必须得到$this->data之类的东西:

Array([Article] => Array(
        [0] => Array
            (
                        [title] => title 1
                    )
        [1] => Array
            (
                        [title] => title 2
                    )
            )
)

那么,我如何“分享”所有选定用户的主题和内容?

4 个答案:

答案 0 :(得分:6)

这些值必须像这样重复

Array([Notification] => Array(
        [0] => Array
            (
                        [user_id] => 4
                        [subject] => subjects
                        [content] => content
                    )
        [1] => Array
            (
                        [user_id] => 6
                        [subject] => subject
                        [content] => contents
                    )
            )
)


$this->Notification->saveAll($data['Notification']); // should work

如果你没有传递任何列值,那么这个蛋糕就会忽略它

答案 1 :(得分:6)

首先,这个数据库设计需要规范化。

在我看来,Notification可能会有很多User与之相关。同时,User可以有多个Notification。因此,

  • 引入名为users_notifications的连接表。
  • 实施HABTM关系:通知 hasAndBelongsToMany 用户

在视图中,您只需使用以下代码自动显示多选表单以获取用户ID:

echo $this->Form->input('User');

发送到控制器的数据格式为:

Array(
    [Notification] => Array
        (
            [subject] => subject
            [content] => contentcontentcontentcontentcontentcontent
        ),
    [User] => Array
        (
            [User] => Array
                (
                    [0] => 4
                    [1] => 6
                )
         )
)

现在,您所要做的就是调用saveAll()函数而不是save()。

$this->Notification->saveAll($this->data);

这就是Cake的做法!

答案 2 :(得分:4)

您将不得不按摩表单的输出以适应Model::saveAll。在您的控制器中:

function action_name()
{
    if ($this->data) {

        if ($this->Notification->saveMany($this->data)) {
            // success! :-)
        } else {
            // failure :-(
        }
    }
}

在你的模特中:

function saveMany($data)
{
    $saveable = array('Notification'=>array());

    foreach ($data['Notification']['user_id'] as $user_id) {

        $saveable['Notification'][] = Set::merge($data['Notification'], array('user_id' => $user_id));
    }

    return $this->saveAll($saveable);
}

这里的好处是你的控制器仍然不知道你的模型的架构,它不应该。

事实上,您可能会在模型中重新定义saveAll,将正确格式化的输入数组移交给parent::saveAll,但本身会处理特殊情况。

答案 3 :(得分:1)

可能有一种更好的方式来做到这一点,但我使用了这种技术:首先,更改表单,以便得到这样的数组:

Array(
    [Notification] => Array
        (
            [subject] => subject
            [content] => contentcontentcontentcontentcontentcontent
        ),
    [selected_users] => Array
        (
            [id] => Array
                (
                    [0] => 4
                    [1] => 6
                )
         )
)

(只需将多选输入的名称更改为selected_users.id)

然后遍历用户ID并单独保存每条记录:

foreach( $this->data[ 'selected_users' ][ 'id' ] as $userId ) {
    $this->data[ 'Notification' ][ 'user_id' ] = $userId;
    $this->Notification->create();  // initializes a new instance
    $this->Notification->save( $this->data );
}
相关问题