2014-02-26 3 views
0

저는 cakePHP로 응용 프로그램을 작성하고 있습니다. 내가 지금하고 싶은 것은 이것이다. 제가 몇 마디로 설명 드리겠습니다 : 저는 2 가지 모델, 항목과 유형학을 가지고 있습니다. 하나의 항목은 많은 유형을 가질 수 있습니다. 그래서 Typology 테이블은 foreign key를 가지고 있습니다 - item_id - 이것은 item을 참조합니다. 이제이 항목을 참조하는 유형이 여전히있는 경우 사용자가 항목을 삭제하지 못하도록하고 싶습니다.다른 객체가 그것을 참조하는 경우 객체의 삭제를 거부하십시오.

내 아이템 모델이 있습니다 :

<?php 
App::uses('AppModel', 'Model'); 
/** 
* Item Model 
* 
* @property ItemLocation $ItemLocation 
* @property ItemCharacteristic $ItemCharacteristic 
* @property FirstSeller $FirstSeller 
* @property SecondSeller $SecondSeller 
* @property User $User 
* @property Contact $Contact 
* @property ItemPicture $ItemPicture 
* @property Typology $Typology 
*/ 
class Item extends AppModel { 
public $name = 'Item'; 

/** 
* Primary key field 
* 
* @var string 
*/ 
    public $primaryKey = 'id'; 
/** 
* Display field 
* 
* @var string 
*/ 
    public $displayField = 'title'; 

/** 
* Validation rules 
* 
* @var array 
*/ 
    public $validate = array(
     'id' => array(
      'blank' => array(
       'rule' => 'blank', 
       'on' => 'create', 
      ), 
     ), 
     'title' => array(
      'words' => array(
       'rule' => array('custom', '/[0-9A-Za-z\._-]/'), 
       'message' => 'The Item name can only contain letters, numbers and spaces.', 
      ), 
      'maxLength' => array(
       'rule' => array('maxLength', 100), 
       'message' => 'The Item name must not be longer than 100 characters.', 
      ), 
      'notEmpty' => array(
       'rule' => array('notEmpty'), 
       'message' => 'The Item name must not be empty.', 
      ), 
      'isUnique' => array(
       'rule' => 'isUnique', 
       'message' => 'This Item name already exists.', 
      ), 
     ), 

     'user_id' => array(
      'numeric' => array(
       'rule' => array('numeric'), 
       //'message' => 'Your custom message here', 
      ), 
      'notEmpty' => array(
       'rule' => array('notEmpty'), 
       'message' => 'Not Empty', 
      ), 
     ), 
     'created' => array(
      'datetime' => array(
       'rule' => array('datetime'), 
       //'message' => 'Your custom message here', 
      ), 
     ), 
    ); 

/** 
* belongsTo associations 
* 
* @var array 
*/ 
    public $belongsTo = array(
     'ItemUser' => array(
      'className' => 'User', 
      'foreignKey' => 'user_id', 
      'conditions' => '', 
      'fields' => '', 
      'order' => '' 
     ) 
    ); 

/** 
* hasMany associations 
* 
* @var array 
*/ 
    public $hasMany = array(
     'ItemTypologies' => array(
      'className' => 'Typology', 
      'foreignKey' => 'item_id', 
      'dependent' => false, 
      'conditions' => '', 
      'fields' => '', 
      'order' => '', 
      'limit' => '', 
      'offset' => '', 
      'exclusive' => '', 
      'finderQuery' => '', 
      'counterQuery' => '' 
     ) 
    ); 

을 그리고 유형론 모델은 이것이다 : 내가보고 쓴이 무엇인지 이제

<?php 
App::uses('AppModel', 'Model'); 
/** 
* Typology Model 
* 
* @property Item $Item 
* @property TypologyCategory $TypologyCategory 
* @property TypologyCondition $TypologyCondition 
* @property User $User 
* @property TypologyPicture $TypologyPicture 
*/ 
class Typology extends AppModel { 
public $name = 'Typology'; 
/** 
* Primary key field 
* 
* @var string 
*/ 
    public $primaryKey = 'id'; 
/** 
* Display field 
* 
* @var string 
*/ 
    public $displayField = 'title'; 

/** 
* Validation rules 
* 
* @var array 
*/ 
    public $validate = array(
     'id' => array(
      'blank' => array(
       'rule' => 'blank', 
       'on' => 'create', 
      ), 
     ), 
     'item_id' => array(
      'numeric' => array(
       'rule' => array('numeric'), 
       'message' => 'Chose Which Object This Typology Belongs To', 
      ), 
      'notEmpty' => array(
       'rule' => array('notEmpty'), 
       'message' => 'Can Not be Empty', 
      ), 
     ), 
     'title' => array(
      'words' => array(
       'rule' => array('custom', '/[0-9A-Za-z\._-]/'), 
       'message' => 'The Typology name can only contain letters, numbers and spaces.', 
      ), 
      'maxLength' => array(
       'rule' => array('maxlength', 50), 
       'message' => 'The Typology name must not be longer than 50 characters.', 
      ), 
      'notEmpty' => array(
       'rule' => array('notEmpty'), 
       'message' => 'Typology Title Can not be Empty', 
      ), 
      'isUnique' => array(
       'rule' => 'isUnique', 
       'message' => 'Typology Name Should be Unique', 
      ), 
     ), 
     'description' => array(
      'words' => array(
       'rule' => array('custom', '/[0-9A-Za-z\._-]/'), 
       'message' => 'The Typology name can only contain letters, numbers and spaces.', 
      ), 
      'maxLength' => array(
       'rule' => array('maxlength', 350), 
       'message' => 'The Typology name must not be longer than 350 characters.', 
      ), 
      'notEmpty' => array(
       'rule' => array('notEmpty'), 
       'message' => 'Description can not be Empty', 
      ), 
     ), 

     'user_id' => array(
      'numeric' => array(
       'rule' => array('numeric'), 
       'message' => 'Chose the user who created this typology', 
      ), 
      'notEmpty' => array(
       'rule' => array('notEmpty'), 
       //'message' => 'Your custom message here', 
      ), 
     ), 
     'created' => array(
      'datetime' => array(
       'rule' => array('datetime'), 
       //'message' => 'Your custom message here', 
      ), 
     ), 
    ); 

/** 
* belongsTo associations 
* 
* @var array 
*/ 
    public $belongsTo = array(
     'TypologyItem' => array(
      'className' => 'Item', 
      'foreignKey' => 'item_id', 
      'conditions' => '', 
      'fields' => '', 
      'order' => '' 
     ), 
     'TypologyUser' => array(
      'className' => 'User', 
      'foreignKey' => 'user_id', 
      'conditions' => '', 
      'fields' => '', 
      'order' => '' 
     ) 
    ); 

, 그리고 사람이 어떤 생각을 가지고 있다면 정말 좋겠 고마워요 :

그리고 typologes가있는 항목을 삭제하려고 할 때 또는이 항목을 표시하지 않는 항목을 삭제하려고 할 때 rror!

Fatal Error 

Error: Call to a member function find() on a non-object 
File: C:\wamp\www\project\app\Model\Item.php 
Line: 449 

어떻게 해결할 수 있습니까?

답변

0

논리가 theotherdy 이미 설명한 것과 비슷합니다.컨트롤러 코드에서

다음과 같이 삭제() 메소드 :

public function delete($id = null) { 
    $this->request->onlyAllow('post', 'delete'); 
    $options = array('conditions' => array('Item.' . $this->Field->primaryKey => $id)); 
    $item = $this->Item->find('first', $options); 
    if (!$item) { 
     throw new NotFoundException(__('Invalid item')); 
    } 
    if (isset($item['Typology']) && count($item['Typology'])) { 
     $this->setFlash(__("Item '%s' is being used by %s Typologies.<br />Cannot delete.", $item['Item']['title'], count($item['Tipology']))); 
    } else { 
     $this->Item->id = $id; 
     if ($this->Item->delete()) { 
      $this->setFlash(__('Item deleted')); 
     } else { 
      $this->setFlash(__('Item was not deleted')); 
     } 
    } 
    $this->redirect(array('action' => 'index')); 
} 
+1

Thanx a Lot @savedario, 코드가 정말 도움이되었습니다. 나는 내가 원했던 Exacly를 얻었다. – landi

0

당신은 DB가 외래 키 제약 조건이 db에 있는지 확인하여 다른 유형으로 참조되는 항목의 삭제를 막고 싶다고 말했을 것입니다. 그런 다음 사용자 인터페이스는 사람들에게 유형에 의해 참조되는 항목을 삭제할 수있는 옵션을 제공해서는 안되지만, 항목에서 유형을 제거 할 수있는 옵션을 제공하고 싶을 수도 있습니다.

나는 당신이 제안하고있는 UI의 종류는 모르지만 (내 머리 꼭대기에서, 체크되지 않은 코드는 오타/오류에 사과하므로) 색인 작업/항목보기가 있다고 가정하면 당신의 ItemsController.php 지수의 행동에 : 당신의보기/아이템 /에서 다음

$items = $this->Item->find('all') 
$this->set('items', $items); 

당신은 할 수 index.ctp :

<?php foreach ($items as $item): ?> 
    <h1><?php echo $item['Item']['name'];?> 
    <?php 
    if(!isset($item['Typology'])||count($item['Typology'])==0){ 
     //ie this items has no Typologies 
     //Create delete button/link for this item 
     } 
    elseif(isset($item['Typology'])&&count($item['Typology'])>0){ 
     //we have some typologies for this item 
     foreach ($item['Typology'] as $typology){ 
      //info about the typology and possible delete button/link 
      } 
     } 
    ?> 
<?php endforeach; ?> 

HTH

을 CONTRO에서 더 자세히 추가 크 로스 - 당신의 모델이 @savedario 말한대로 그 제약 조건 위반, 그래서이있는 경우 실패 후 적절한 외래 키 제약

$this->Item->delete() 

을 설정하는 경우 @savedario의 대답

에 확대, 당신은

if ($this->Item->delete()) 

과 성공을위한 테스트하거나 좀 더 우아하고 일반적으로 여기에 다 생각하는 제외한 @savedario이 설명대로, 한 단계 더 갈 수있다 : 기록이 연결되어있는 경우 http://joshuapaling.com/post/catching-integrity-constraint-violations-when-deleting-records 및 예외를 throw하는 당신이 할 수있는 다음 (의 joshuapaling 블로그에서 복사) 다음 테스트 :

try { 
    if ($this->MyModel->delete()) { 
     $this->Session->setFlash('Record deleted', 'default', array(), 'good'); 
    } else { 
     $this->Session->setFlash('Record was not deleted. Unknown error.', 'default', array(), 'bad'); 
    } 
} catch (Exception $e) { 
    $this->Session->setFlash("Delete failed. {$e->getMessage()}", 'default', array(), 'bad'); 
} 
+0

아니라 UI가 꽤 아직 구축하지 않지만 메신저 먼저 논리를 구축을 위해 노력. 내가 요점을 알지만 요점은 사용자가 여전히 URL을 통해 삭제 작업에 액세스 할 수 있다는 것입니다. 그 중 하나가 필요하지 않습니다. 즉, 요즘에는 모든 키 유형을 포함하는 모든 유형을 계산하는 방법이나 쿼리가 있는지 질문합니다. items보다 크고> 1이면 delete를 거부하거나 false를 반환하고, 그렇지 않으면 delete를 허용하고 true를 반환합니다. – landi

관련 문제