使用CodeIgniter DataMapper ORM保存一对一关系



我的数据库模式:

CREATE TABLE IF NOT EXISTS `customers` 
(
`id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`person_id` smallint(5) unsigned NOT NULL,
`status` tinyint(1) unsigned NOT NULL DEFAULT 1,
PRIMARY KEY (`id`),
KEY `fk_customers_persons_idx` (`person_id`)
);
CREATE TABLE IF NOT EXISTS `persons` 
(
`id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(64) NOT NULL,
`phone` char(10) DEFAULT NULL,
`mobile` char(10) DEFAULT NULL,
`email` varchar(64) NOT NULL,
`date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`data_updated` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);

这是我的控制器代码:

class Test extends CI_Controller {
public function index()
{
// Faking POST values
$_POST = array(
// Person info
'name' => 'Paulo Freitas',
'phone' => 'xxxxxxxxxx',
'email' => 'xx@xxxxxxxxxxxx.xx',
// Customer info
'status' => 2
);
// Utility function
function factory_from($class, $fields)
{
$CI =& get_instance();
$input = array();
foreach ($fields as $field) {
$input[$field] = $CI->input->post($field) ?: null;
}
$obj = new $class;
$obj->from_array($input);
return $obj;
}
// Save person
$person = factory_from('Person', array(
'name',
'phone',
'mobile',
'email'
));
$person->save();
// Save customer
$customer = factory_from('Customer', array(
'status'
));
$customer->save($person);
var_dump($customer->id); // New customer id
}
}

我是CodeIgniter的DataMapper ORM的新手,我有点迷失了如何确保只有在成功存储相关客户时才能存储一个人。例如,如果我验证了一个客户status,但它失败了,为了存储该客户,我以前必须存储其相关人员。。。如果我不能存储客户,如何回滚新人?(在实际场景中,我有一个personsindividualsuserscustomers表,只有在所有成功的情况下,我才需要存储它们)

如何在此处使用交易?是的,我已经阅读了关于使用交易的文档,但我不明白,我已经花了几个小时了。提前谢谢!

更新

我黑了我的控制器一点,现在它似乎工作了,有更好的方法来实现这一点吗?

新控制器:

class Test extends CI_Controller {
public function index()
{
// Faking POST values
$_POST = array(
// Person info
'name' => 'Paulo Freitas',
'phone' => 'xxxxxxxxxx',
'email' => 'xx@xxxxxxxxxxxx.xx',
// Customer info
'status' => 2
);
// Utility functions
function factory_from($class, $fields)
{
$CI =& get_instance();
$input = array();
foreach ($fields as $field) {
$input[$field] = $CI->input->post($field) ?: null;
}
$obj = new $class;
$obj->from_array($input);
return $obj;
}
function get_errors()
{
$errors = array();
foreach (func_get_args() as $obj) {
$errors += $obj->error->all;
}
return $errors;
}
// Initialize person
$person = factory_from('Person', array(
'name',
'phone',
'mobile',
'email'
));
// Initialize customer
$customer = factory_from('Customer', array(
'status'
));
// Start transaction
$person->trans_begin();
if ($person->save()
&& $customer->save($person)) {
// If we can save all data, commit!
$person->trans_commit();
// Dump new customer id
var_dump($customer->id);
} else {
// Otherwise, rollback all!
$person->trans_rollback();
// Dump all errors
var_dump(get_errors($person, $customer));
}
}
}
// Begin transaction
$p->trans_begin();
// Attempt to save person
$p->save();
// Check status of transaction
if ($p->trans_status() === FALSE)
{
// Transaction failed, rollback
$p->trans_rollback();
// Add error message
$u->error_message('transaction', 'The transaction failed to save (insert)');
}
else
{
//since the person has been saved, then we can now process the customer
// Begin transaction
$c->trans_begin();
// Attempt to save person
$c->save($p);
if( $c->trans_status === TRUE ){
$p->commit(); 
$c->commit();
}
}
/*
* you can nest a lot of if statements depending on the number of objects you want to save
* I followed whats exactly in the documentation for that. So give it a try, it should run.
* dont forget to create $c and $p as datamapper objects.
*/

最新更新