我已经能够使用 CakePHP 的 saveAll 方法同时创建“成员”并将它们注册到“事件”中(创建 HABTM 链接记录),这非常棒。例如,此代码创建两个新的“Members”,并将每个人的记录添加到“EventsMember”表中,将它们注册为“Event”10:
$data = array(
'0' => array(
'Member' => array('email' => '[email protected]'),
'Event' => array('id' => 10)
),
'1' => array(
'Member' => array('email' => '[email protected]'),
'Event' => array('id' => 10)
)
);
$this->Member->saveAll($data);
但是,“EventsMember”表中的记录还有一个名为“角色”的字段,其中包含“演示者”或“主持人”或“参加者”等内容,我想在创建关系时保存该数据。我尝试了这个,但它不起作用(“EventsMember”“角色”字段始终为空):
$data = array(
'0' => array(
'Member' => array('email' => '[email protected]'),
'Event' => array('id' => 10),
'EventsMember' => array('role' => 'Host')
),
'1' => array(
'Member' => array('email' => '[email protected]'),
'Event' => array('id' => 10),
'EventsMember' => array('role' => 'Attendee')
)
);
$this->Member->saveAll($data);
我想知道这是否可能,并且我是否必须使用某种回调(例如 beforeSave 或 afterSave)来完成此操作?我读到,使用 saveAll 时这些回调存在一些问题,因此我正在寻找有关此处最佳实践的任何提示。
Thanks!
编辑:我采纳了 Adam 的建议并对我的模型进行了以下更改:
// Event.php
var $hasMany = array('EventsMember');
// Member.php
var $hasMany = array('EventsMember');
// EventsMember.php
var $belongsTo = array('Event', 'Member');
然后在我的控制器中,我的代码看起来几乎与我的第二个示例相同,除了我调用了saveAll()
方法从EventsMember
模型,如文档中所述:
$data = array(
'0' => array(
'Member' => array('email' => '[email protected]'),
'Event' => array('id' => 10),
'EventsMember' => array('role' => 'Host')
),
'1' => array(
'Member' => array('email' => '[email protected]'),
'Event' => array('id' => 10),
'EventsMember' => array('role' => 'Attendee')
)
);
$this->EventsMember->saveAll($data);
结果没有Member
or EventsMember
记录完全被保存了。我尝试从以下位置触发保存Member
model ($this->Member->saveAll($data);
)这节省了Member
记录,但不是加入EventsMember
记录。
我尝试删除预先存在的 HABTM 关联,但没有任何区别。这beforeSave
的方法EventsMember
当我打电话时模型被触发$this->EventsMember->saveAll($data);
但看起来它实际上不会保存任何东西。
我很受阻。
更新:事实证明,没有创建任何记录,因为加入记录都是使用事件 id 和会员 id 0 创建的,这违背了我在这两个字段组合上的唯一键(也就是说,没有会员可以注册事件两次)。
这是否表明加入模型 saveAll 功能未按记录工作,因为未创建成员记录(意味着加入记录中没有可使用的成员 id),并且现有事件 id 未传递到加入活动会员记录吗?
结论:我将控制器更改为在每个记录上循环并尝试$this->EventsMember->saveAll($data)
对于数组的每个索引,而不是一次传递整个数组。它有效,但比我的第一个示例(在最顶部)慢得多。请注意,我正在使用事务,所以也许使用atomic => false;
选项会加快速度,同时仍然允许我从任何无效记录中恢复。
最重要的是,如果您需要在连接表记录中保存额外的数据,则必须一次处理一个数据。如果没有,请使用顶部的方法以获得最佳性能。