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

在CakePHP中为一个模型保存多条记录,cakephp,save,cakephp-1.3,Cakephp,Save,Cakephp 1.3,我想为一个模型保存几个记录。如果不是因为问题,使用saveAll()可以很容易地做到这一点: 我有一个通知表单,我从一个和两个字段中分别为主题和内容选择多个用户。现在,当我输出$this->data包含的内容时,我有: Array([Notification] => Array ( [user_id] => Array ( [0] => 4 [1] => 6

我想为一个模型保存几个记录。如果不是因为问题,使用
saveAll()
可以很容易地做到这一点:

我有一个通知表单,我从一个
和两个字段中分别为主题和内容选择多个用户。现在,当我输出
$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
                    )
            )
)

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

可能有一种更为简单的方法,但我使用了这种技术:首先,更改表单,以便获得如下数组:

Array(
    [Notification] => Array
        (
            [subject] => subject
            [content] => contentcontentcontentcontentcontentcontent
        ),
    [selected_users] => Array
        (
            [id] => Array
                (
                    [0] => 4
                    [1] => 6
                )
         )
)
(只需将multiselect输入的名称更改为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 );
}

这些值必须像这样重复

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

如果不传递任何列值,此蛋糕将忽略它

您将不得不调整表单的输出以适应
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
,但它本身会处理特殊情况。

首先,此数据库设计需要规范化

在我看来,
通知
可以有许多与之相关的
用户。同时,一个
用户
可以有许多
通知
s。所以,

  • 引入名为users\u notifications的联接表
  • 实现HABTM关系:通知hasandbelongtomanyUser
在视图中,您可以简单地使用以下代码自动打开multi-select表单以获取用户ID:

echo $this->Form->input('User');
发送到控制器的数据将采用以下形式:

Array(
    [Notification] => Array
        (
            [subject] => subject
            [content] => contentcontentcontentcontentcontentcontent
        ),
    [User] => Array
        (
            [User] => Array
                (
                    [0] => 4
                    [1] => 6
                )
         )
)
现在,您所要做的就是调用saveAll()函数,而不是save()


这就是蛋糕的制作方法

谢谢你的回答。我认为这是一种更为“巧妙”的方法。但是,我会直截了当地说。谢谢你的回复。这是一个很好的建议,使一个单独的方法,将这样做!我将此代码放在服务器上,似乎saveAll()不起作用。新数组看起来很平滑,我将其传递给saveAll(),但它不保存任何内容。我删除了此方法中的验证,但没有成功。有什么问题吗?谢谢你的回答!我认为有一个用户有很多通知就足够了。但现在我明白了,我还需要一个通知,许多用户是为了正确提交表格。不过,我只有一个问题:我有一个Users HasandBelongTomany Notifications关系,还有UsersController和NotificationsController。我需要UsersNotificationsController吗?或者我将分别使用$this->User->Notification,在需要关系时使用$this->Notification->User?如果您开始增加连接关系的复杂性,则可能需要model UsersNotification。例如:如果您想存储用户是否已阅读通知,则连接表将变为:id-User\u id-Notification\u id-read。现在,您必须将这种“贯穿”关系建模为一个单独的实体。你可以在这里了解更多:再次感谢。不过,我还有一个问题:为什么在表中插入新关联时会删除联接表中的所有关联?这对我来说毫无意义。为了停止这种“wierd”行为,我必须在HABTM的关系定义数组中设置
'unique'=false
?HABTM关系基于Post-Tag类比,其中Post具有唯一的标记(相同的标记不会出现两次)。所以,如果你想编辑你帖子的标签,这种行为一点也不奇怪!:)使用'unique'=false是正确的方法。将新的单个标记添加到帖子时使用。
$this->Notification->saveAll($this->data);