【发布时间】:2011-02-26 21:44:29
【问题描述】:
我已经能够使用 CakePHP 的 saveAll 方法同时创建“成员”并将它们注册到一个“事件”中(创建 HABTM 链接记录),这太棒了。例如,此代码创建了两个新的“成员”,并将每个人的记录添加到“EventsMember”表中,将它们注册为“事件”10:
$data = array(
'0' => array(
'Member' => array('email' => 'nobody@nowhere.com'),
'Event' => array('id' => 10)
),
'1' => array(
'Member' => array('email' => 'somebody@nowhere.com'),
'Event' => array('id' => 10)
)
);
$this->Member->saveAll($data);
但是,“EventsMember”表中的记录还有一个名为“role”的字段,其中包含“Presenter”或“Host”或“Attendee”之类的内容,我想在创建关系时保存这些数据。我试过了,但它不起作用(“EventsMember”“角色”字段始终为空白):
$data = array(
'0' => array(
'Member' => array('email' => 'nobody@nowhere.com'),
'Event' => array('id' => 10),
'EventsMember' => array('role' => 'Host')
),
'1' => array(
'Member' => array('email' => 'somebody@nowhere.com'),
'Event' => array('id' => 10),
'EventsMember' => array('role' => 'Attendee')
)
);
$this->Member->saveAll($data);
我想知道这是否可能,是否可能我必须使用某种回调,如 beforeSave 或 afterSave 来完成这项工作?我读到在使用 saveAll 时这些回调存在一些问题,因此我正在寻找有关最佳实践的任何提示。
谢谢!
编辑:我听取了 Adam 的建议,并对我的模型进行了以下更改:
// Event.php
var $hasMany = array('EventsMember');
// Member.php
var $hasMany = array('EventsMember');
// EventsMember.php
var $belongsTo = array('Event', 'Member');
然后在我的控制器中,我的代码看起来与我的第二个示例几乎相同,除了我从 EventsMember 模型中调用了 saveAll() 方法,如文档中所述:
$data = array(
'0' => array(
'Member' => array('email' => 'nobody@nowhere.com'),
'Event' => array('id' => 10),
'EventsMember' => array('role' => 'Host')
),
'1' => array(
'Member' => array('email' => 'somebody@nowhere.com'),
'Event' => array('id' => 10),
'EventsMember' => array('role' => 'Attendee')
)
);
$this->EventsMember->saveAll($data);
结果是根本没有保存Member 或EventsMember 记录。我尝试从Member 模型($this->Member->saveAll($data);)触发保存,这保存了Member 记录,但没有加入EventsMember 记录。
我尝试删除预先存在的 HABTM 关联,但没有任何区别。 EventsMember 模型的 beforeSave 方法在我调用 $this->EventsMember->saveAll($data); 时被触发,但看起来它实际上不会保存任何东西。
我被困住了。
更新:事实证明,没有创建任何记录,因为加入记录都是使用 0 的事件 ID 和成员 ID 创建的,这违背了我在这两个字段上组合的唯一键(也就是说,没有成员可以参加一个活动两次)。
这是否表明加入模型 saveAll 功能没有按文档说明工作,因为没有创建成员记录(意味着在加入记录中没有要使用的成员 ID),并且现有的事件 ID 不是是否也传递给加入的 EventsMember 记录?
VERDICT:我将控制器更改为在每条记录上循环,并尝试为数组的每个索引使用$this->EventsMember->saveAll($data),而不是一次传递整个数组。它有效,但比我的第一个示例(在最顶部)慢得多。请注意,我正在使用事务,因此使用 atomic => false; 选项可能会加快处理速度,同时仍允许我从任何无效记录中恢复。
底线,如果您需要在连接表记录中保存额外的数据,您必须一次处理一个。如果没有,请使用顶部的方法以获得最佳性能。
【问题讨论】:
标签: cakephp transactions