他のオブジェクトがそれを参照している場合、オブジェクトの削除を拒否する

StackOverflow https://stackoverflow.com//questions/22046249

  •  21-12-2019
  •  | 
  •  

質問

私はCakePhpと一緒にアプリを構築しています、そして私はそれの中でとても新しいです。私が今やりたいことはこれです。いくつかの単語で説明しましょう:私は2つのモデル、アイテム、および類似体を持っています。1つのアイテムには多くの類型化があります。そのため、Typology Tableには外部キー - 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;
    }
} 
.

字型のアイテムやアイテムを削除しようとすると、このエラーが表示されません。

Fatal Error

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

どのように私はそれを解決することができます!!

役に立ちましたか?

解決

ロジックは、

他のヒント

私はあなたのDBが他の字型の制約がDBにあることを確認することによって、他の類似体によって参照されるアイテムの削除を防ぐことを望んでいると思います。それからあなたのUIは人々に典型的に言及されているアイテムを削除するオプションを与えてはいけませんが、あなたは彼らにアイテムからの類型を削除するオプションを彼らに与えたいかもしれません。

あなたが提案しているのはどのような様式であるかを理解していませんが、(私の頭の上から、チェックされていないコードのないコード外の謝罪/エラーを謝罪する)は、あなたがアイテムのインデックスアクション/ビューを持っていた、あなたはこれを持っているかもしれません。あなたのItemsController.phpインデックスアクション:

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

それからあなたの見解/ items / index.cotpあなたは持っているかもしれません:

<?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

コントローラの詳細を追加する - @Savedarioの答えの拡大

モデルが適切な外部キー制約で設定されている場合は、

$this->Item->delete()
.

はこれらの制約の違反があると失敗するため、@Savedarioが言うように、

で成功をテストできます
if ($this->Item->delete())
.

またはあなたはさらに一歩進むことができます、@Savedarioは展示されていますが、ここでよりエレガントにそして一般的に行われていると思います。http://joshuapaling.com/post/catching-integrity-Constraint-violations- "REL=" NOFOLLOW "> http://joshuapaling.com/post/catching-integrity-constraint-violations-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');
}
.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top