在CakePHP中为一个模型保存多条记录
我想为一个模型保存多条记录。这已经与saveAll()
做得相当容易,如果它不是为一个问题:在CakePHP中为一个模型保存多条记录
我有一个通知的形式,在这里我选择分别从<select>
和两个字段中的多个用户,主题和内容。现在,当我输出什么$this->data
包含,我有:
Array([Notification] => Array
(
[user_id] => Array
(
[0] => 4
[1] => 6
)
[subject] => subject
[content] => the-content-here
)
)
我读过蛋糕1.3书,为了保存多个记录的模型,你必须有$this->data
类似:
Array([Article] => Array(
[0] => Array
(
[title] => title 1
)
[1] => Array
(
[title] => title 2
)
)
)
那么,我如何将主题和内容“分享”给所有选定的用户呢?
首先,这个数据库设计需要正常化。
在我看来,像一个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的方法!
有可能是这样做的更加cakey方式,但我已经使用这种技术:首先,改变形式,让你得到一个这样的数组:
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);
}
这些值必须重复这样
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
如果不传递任何列值,这个蛋糕会忽略它
谢谢你的回答! – linkyndy 2010-11-23 20:48:56
你将有按摩你的表单输出,以满足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
,但本身处理特殊情况。
谢谢你的回答。我认为这是一个更加“干脆”的方法。但是,我会采取“直截了当”的方式。 – linkyndy 2010-11-23 20:41:44