Реализация ondelete ограничить ассоциацию в CakePHP - PullRequest
1 голос
/ 03 сентября 2010

У меня есть Событие, принадлежащее месту проведения ассоциации.Когда пользователь пытается удалить место, я не хочу, чтобы это происходило, когда с ним связано одно или несколько событий.Какой самый автоматический способ сделать это?

Ответы [ 3 ]

1 голос
/ 04 сентября 2010

Если вы установили встречный кэш для отношения и используете 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' ));
        }
    }
?>
0 голосов
/ 07 сентября 2010

Если вы используете таблицы InnoDB, вы можете добавить ограничение внешнего ключа, которое препятствует удалению объектов, если у них есть события и если идентификатор объекта обновляется, он автоматически обновляет значения venue_id в таблице событий.

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

Или как-то так.

Это просто опция, которую вы можете использовать, если хотите, которая добавляет дополнительную надежность на уровне данных в случае, если в вашем приложении есть ошибка, препятствующая обнаружению ограничения в коде. Я бы добавил его в код, чтобы ваше приложение не получало предупреждение / ошибку SQL.

0 голосов
/ 03 сентября 2010

Я бы просто написал код, вероятно, на модели Venue.

См. http://book.cakephp.org/view/685/beforeDelete

...