在CakePHP中实现ondelete限制关联

时间:2010-09-03 08:35:24

标签: cakephp associations

我有Event belongsTo Venue协会。 当用户尝试删除场地时,我不希望在一个或多个事件与之关联时发生。 什么是最自动化的方式呢?

3 个答案:

答案 0 :(得分:1)

如果您在关系上设置了counterCache并使用deleteAll而不是delete,则可以根据附加到场地的事件数量将条件传递给删除查询。

<?php
    /**
     *  Event Model
     *
     *  uses table events
     *  @fields array( id, venue_id, ... )
     *  
     */

    class Event extends AppModel {

        public $name = "Event";

        // setup the relationship to venues table with a counterCache
        public $belongsTo = array(
            'Venue' => array(
                'className' => 'Venue',
                'counterCache' => true
            )
        );
    }
?>

<?php
    /**
     *  Venue Model
     *
     *  uses venues table
     *  @fields array( id, event_count, ... )
     *  
     */

    class Venue extends AppModel {

        public $name = "Venue";

        // setup the relationship to events table
        public $hasMany = array(
            'Event' => array(
                'className' => 'Event',
            )
        );
    }
?>

<?php
    /**
     *  Venues Controller
     *
     *  example of a delete function using deleteAll to include conditions instead of delete which only takes an id
     *  
     */

    class VenuesController extends AppController {

        /**
         *  delete a venue
         *
         *  checks to make sure a venue has no events and then deletes it.
         */

        public function delete( $id = null ){
            if( $id ){
                // make sure the conditions array checks for event_count re: counterCache
                $conditions = array( 'Venue.id' => $id, 'Venue.event_count' => 0 );

                // run deleteAll but enable callbacks so that the deleteAll functions as a normal delete
                ( $this->Venue->deleteAll( $conditions, true, true )) ? $this->Session->setFlash( "Event deleted" ) : $this->Session->setFlash( "Event still has attached events and could not be deleted." ); 
            }
            return $this->redirect( array( 'controller' => 'venues', 'action' => 'index' ));
        }
    }
?>

答案 1 :(得分:0)

我只是编码它,可能是在Venue模型上。

请参阅http://book.cakephp.org/view/685/beforeDelete

答案 2 :(得分:0)

如果您正在使用InnoDB表,则可以添加一个外键约束,以阻止Venues在有事件时被删除,如果Venue ID已更新,它会自动更新events表中的venue_id值。

ALTER TABLE  `events` ADD FOREIGN KEY (  `venue_id` ) REFERENCES  `venues` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE ;

或类似的东西。

如果您希望在数据级别添加额外的健壮性,以防您的应用中存在阻止在代码中检测到限制的错误,那么它只是一个选项。我会在代码中添加它,以便您的应用程序不会收到SQL警告/错误。