2012-09-23 1 views
1

내 데이터베이스 스키마 :저장 일대일 관계

class Test extends CI_Controller { 
    public function index() 
    { 
     // Faking POST values 
     $_POST = array(
      // Person info 
      'name' => 'Paulo Freitas', 
      'phone' => 'xxxxxxxxxx', 
      'email' => '[email protected]', 
      // Costumer 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 costumer 
     $costumer = factory_from('Costumer', array(
      'status' 
     )); 
     $costumer->save($person); 
     var_dump($costumer->id); // New costumer id 
    } 
} 

내가 CodeIgniter의의 DataMapper의 ORM에 새로 온 사람과 손실 비트 :

CREATE TABLE IF NOT EXISTS `costumers` (
    `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_costumers_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`) 
); 

여기 내 컨트롤러 코드입니다 내가 어떻게 성공적으로 관련 costumer을 저장할 사람을 저장 확신 할 수 있습니다. 예를 들어, costumer status의 유효성을 검사하고 실패하면, 해당 costumer를 저장하려면 이전에 관련된 사람을 저장해야했습니다 ... costumer를 저장할 수 없으면 어떻게 새 사람을 롤백 할 수 있습니까? (실제 시나리오에서 나는 persons, individuals, userscostumers 테이블을했습니다, 나는 모두가 성공하는 경우에만이를 저장해야) 내가 여기 트랜잭션을 사용할 수있는 방법

? 그래, 이미 거래를 사용하는 것에 대한 문서를 읽었으나 알아낼 수는 없지만 지금까지 몇 시간 동안 그 문제에 매달 렸습니다. 미리 감사드립니다.

UPDATE 내 컨트롤러 비트를 해킹하고 지금은 이것을 달성하기 위해 더 나은 방법이, 작동하는 것 같다

?

새로운 컨트롤러 :

class Test extends CI_Controller { 
    public function index() 
    { 
     // Faking POST values 
     $_POST = array(
      // Person info 
      'name' => 'Paulo Freitas', 
      'phone' => 'xxxxxxxxxx', 
      'email' => '[email protected]', 
      // Costumer 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 costumer 
     $costumer = factory_from('Costumer', array(
      'status' 
     )); 

     // Start transaction 
     $person->trans_begin(); 

     if ($person->save() 
       && $costumer->save($person)) { 
      // If we can save all data, commit! 
      $person->trans_commit(); 

      // Dump new costumer id 
      var_dump($costumer->id); 
     } else { 
      // Otherwise, rollback all! 
      $person->trans_rollback(); 

      // Dump all errors 
      var_dump(get_errors($person, $costumer)); 
     } 
    } 
} 

답변

1
// 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. 
*/