CakePHP使用saveAll:如何使用HABTM链接记录保存额外的数据? [英] CakePHP using saveAll: How do I save extra data with the HABTM link record?

查看:304
本文介绍了CakePHP使用saveAll:如何使用HABTM链接记录保存额外的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经能够使用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'=& (
'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');然后在我的控制器中,我的代码看起来和我的第二个例子几乎完全相同,除了我调用了<$(







$ b < EventsMember 模型中的c $ c> saveAll()
方法,如文档中所述:

  $ data = array(
'0'=&array; 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);

结果没有会员 c $ c> EventsMember 记录已保存。我尝试触发从成员模型( $ this-> Member-> saveAll($ data); ),这保存了会员记录,但不保存加入 EventsMember 记录。



我试图删除已有的HABTM关联,它没有什么区别。当调用 $ this->时,会触发 EventsMember 模型的 beforeSave 事件成员 - > saveAll($ data); 但看起来它不会实际保存任何东西。



/ p>

更新:事实证明,没有创建记录,因为连接记录都是使用事件ID和成员ID为0创建的,这违背了我所拥有的唯一键这两个字段组合在一起(也就是说,没有成员可以在一个事件中注册两次)。



这表明连接模型saveAll功能不能正常工作,因为成员记录未创建(意味着在加入记录中没有要使用的成员ID),并且现有的事件ID未传递到加入EventsMember记录?



VERDICT:我更改了控制器以循环每个记录,并为数组的每个索引尝试 $ this-> EventsMember-> saveAll($ data) ,而不是一次传递整个数组。它工作,但是明显慢于我的第一个例子(在最顶部)。注意,我使用事务,所以也许使用 atomic => false; 选项会加快速度,同时仍然允许我从任何无效的记录恢复。



底线,如果你需要保存额外数据在连接表记录中,你必须一次处理一个。

解决方案

您可以使用这种情况下的加入模型


I have been able to use CakePHP's saveAll method to simultaneously create 'Members' and enroll them in an 'Event' (creating the HABTM link record), which is awesome. For example, this code creates two new 'Members' and adds a record for each of them to the 'EventsMember' table, enrolling them 'Event' 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);

However, the record in the 'EventsMember' table also has a field called 'role' that holds something like "Presenter" or "Host" or "Attendee" and I would like to save that data when I create the relationship. I tried this and it does not work (the 'EventsMember' 'role' field is always blank):

$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);

I'm wondering if this is even possible, and if maybe I have to use some kind of callback like beforeSave or afterSave to get this done? I've read that there are some problems with these callbacks when using saveAll, so I'm looking for any tips on what would be the best practice here.

Thanks!

EDIT: I took Adam's advice and made the following changes to my models:

// Event.php
var $hasMany = array('EventsMember');

// Member.php
var $hasMany = array('EventsMember');

// EventsMember.php
var $belongsTo = array('Event', 'Member');

Then in my controller, my code looked almost identical to my second example, except I called the saveAll() method from the EventsMember model, as described in the documentation:

$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);

The result was no Member or EventsMember records were saved at all. I tried triggering the save from the Member model ($this->Member->saveAll($data);) and this saved the Member records, but not the joining EventsMember records.

I tried removing the pre-existing HABTM associations, and it made no difference. The beforeSave method of the EventsMember model is getting triggered when I call $this->EventsMember->saveAll($data); but it looks like it won't actually save anything.

I'm stymied.

UPDATE: It turns out that no records were created because the joining records were all being created with Event ids and Member ids of 0, which goes against a unique key I have on those two fields combined (that is, no Member can enroll in an Event twice).

Does this suggest that the join model saveAll functionality is not working as documented, since the Member record isn't getting created (meaning there is no Member id to use in the joining record), and the existing Event id is not being passed to the joining EventsMember record either?

VERDICT: I changed the controller to loop on each record and attempt to $this->EventsMember->saveAll($data) for each index of the array, instead of passing the entire array at once. It worked, but was significantly slower than my first example (at the very top). Mind you, I am using transactions, so perhaps using the atomic => false; option would speed things up, while still allowing me to recover from any invalid records.

Bottom line, if you need to save extra data in join table records, you have to process them one at a time. If not, use the method at the top for the best performance.

解决方案

You can use The Join Model in this case.

这篇关于CakePHP使用saveAll:如何使用HABTM链接记录保存额外的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆