我从CakePHP开始。我有非常简单的模型:
我创建了一个用户,当我以该用户身份登录时,如果User和Companies之间没有任何关系,我将被重定向到Companies控制器的add操作。这一切都已完成,并且运作良好。
我的“大”问题是:当我保存公司时,我必须保存公司的数据以及当前用户和创建公司之间的关系。这一切都必须在交易中完成,因为我不想要“孤儿”公司。但是我应该把这段代码放在哪里?在公司模型中创建一个save()函数并在保存后创建关系?在公司模型中创建一个afterSave()函数?将所有代码放在CompaniesController的add动作中?我不认为这最后一个选项是个好主意,商业逻辑必须在模型中,不是吗?
我知道这一定是一个非常基本的问题,但我是CakePHP和MVC的新手。
答案 0 :(得分:3)
这一切都必须在交易中完成,因为我不想要“孤儿”公司
CakePHP已经提供了一个功能,可以完全满足您的要求:saveAssociated(也可通过saveAll访问)
Model :: saveAssociated(array $ data = null,array $ options = array())
options数组有多个最相关的键:
atomic:如果为true(默认值),将尝试在单个事务中保存所有记录。如果数据库/表不支持事务,则应设置为false。
因此不需要任何额外的代码,只需调用saveAssociated
即可调用save
。
确保保存的数据是hasMany through relationship的正确格式 - 如果有疑问,它应该与包含相同数据的查找格式相同:
class ExampleController extends AppController {
function example() {
$data = array(
'Company' => array(
'name' => 'My Company'
),
'CompaniesUser' => array(
'user_id' => 'My User Id'
)
);
$this->Company->saveAssociated($data);
}
}
这将保存新公司和与给定用户的关系 - 或者无法在数据库中修改任何内容。
答案 1 :(得分:1)
你的第一个问题的答案是你不需要在模型中插入额外的代码,这可以在这样的控制器中完成
<强> CompanyController.php 强>
$datasource = $this->Company->getDataSource();
try{
$datasource->begin();
if(!$this->Company->save($data)
throw new Exception();
if(!$this->User->save($data_one)
throw new Exception();
$datasource->commit();
} catch(Exception $e) {
$datasource->rollback();
}
第二个问题的答案有点困难。我个人觉得Cakephp充满了糟糕的做法。它应该遵循 Fat Model和Skinny Controller 概念。如果您想编写MVC的最佳实践,那么模型层将包含与蛋糕基本函数不同的所有业务逻辑。