2014-02-26 86 views
0

我正在用cakePHP構建一個應用程序,而且我很新。我現在想做的是這個。讓我用幾句話來解釋:我有2個模型,Item和Typologies。一個項目可以有許多類型。所以類型學表有一個外鍵 - item_id - 它指的是項目。現在我想阻止用戶刪除項目,如果仍然有類型引用這個項目。如果其他對象引用它,則拒絕刪除對象

我的產品型號是:

<?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' => '' 
     ) 
    ); 

現在我所看到的和寫的是這樣的,如果任何人有任何想法,我真想欣賞它:

// using app/Model/Item.php 
// In the following example, do not let an Item to be deleted if it 
// still contains Typologies Attached to it. 
// A call of $this->Typology->delete($id) from TypologiesController.php has set 
// $this->id . 
// Assuming 'ItemTypologies hasMany Typology', we can access $this->Typoogy 
// in the model. 

public function beforeDelete($cascade = true) { 
    $count = $this->Typology->find('count', array('conditions' => array('item_id' => $this->Typology->id))); 
    if ($count == 0) { 
     return true; 
    } else { 
     return false; 
    } 
} 

而當我試圖刪除一個項目有typologes或一個項目它不顯示這個e 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已經解釋。

在控制器代碼如下delete()方法:

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

我會說你想讓你的數據庫防止刪除其他類型的引用的項目,確保這些外鍵約束在數據庫中。那麼你的用戶界面不應該讓人們刪除類型學引用的項目,但是也許你想讓他們選擇從項目中刪除類型。

我不知道你在提議什麼樣的用戶界面,但是(關閉我的頭頂,未經檢查的代碼,因此對任何錯誤/錯誤表示歉意),說你有一個索引操作/項目視圖,你可能會有這個在ItemsController.php index動作:

$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

IN THE CONTRO增加更多的細節LLER - 擴大對@savedario的回答

如果你的模型設置了正確的外鍵約束,然後

$this->Item->delete() 

如果有任何違反這些限制的話,作爲@savedario說會失敗,您可以測試成功與

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

,或者你可以走一步,因爲@savedario說明,但我認爲這是更優雅,一般在這裏完成:http://joshuapaling.com/post/catching-integrity-constraint-violations-when-deleting-records並拋出一個異常,如果有鏈接的記錄,你可以然後在下面的(從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訪問刪除操作,我也不想這麼做,這就是爲什麼即時通訊詢問是否有方法或查詢首先計算所有類型,項目,如果有更多> 1,拒絕刪除或返回false,否則允許刪除,返回true。 – landi

相關問題