Мягко удаленные данные CakePHP все еще отображаются в ассоциациях моделей

Я использую SoftDeletableBehavior для своей модели адресов.

Это устанавливает его так, что когда вы удаляете адрес, он на самом деле не удаляет его, вместо этого устанавливает столбец deleted в базе данных в 1.

Это также изменяет ваш запрос в функции beforeFind модели Address, чтобы извлекать только записи, где deleted != 1

Это работает, когда я просматриваю адреса через контроллер адресов, например /addresses/show/43.

Однако мой Users контроллер hasMany обращается. Поэтому, когда я нахожусь в контроллере пользователей и вызываю $this->find('first');, чтобы получить пользователя, я также получаю связанные с ним адреса. Я ожидаю, что это НЕ даст мне (мягко) удаленные адреса, но это ДЕЙСТВУЕТ. Также никогда не вызывается фильтр beforeFilter для модели адреса.

Как правильно с этим справиться?


Обновлять.

Видимо, когда я делаю это:

$data = $this->User->find('first',array('conditions' => array('User.id' => $id),'recursive' => 2));
    

У меня есть массив $data['User] и массив $data['Address] (вместе с другими).

Но это не использует фильтр beforeFind в модели адреса. Значит у меня неправильные данные.

Но если я сделаю это:

$data = $this->User->find('first',array('conditions' => array('User.id' => $id),'recursive' => 2));
$data['Address'] = $this->User->Address->find('all',array('conditions'=>array('user_id'=>$id)));

Затем он использует фильтр beforeFind для модели Address и возвращает правильные данные.

(конечно в другом формате [Address][0][id] vs [Address][0][Address][id])

Чего я не понимаю, так это того, что если связанные данные, которые извлекаются, не используют свою собственную модель для поиска своих данных, то в чем смысл? Разве это не одна из основных целей MVC?

Может я просто не понимаю? Или я что-то упускаю?

Может кто-нибудь просветить меня?


person JD Isaacks    schedule 21.02.2011    source источник


Ответы (3)


Не можете ли вы поставить это условие в вашей ассоциации?

<?php

class User extends AppModel {
    var $hasMany = array(
        'Address' => array(
            'conditions' => array('NOT' => array('Address.deleted' => '1')),
        )
    );
}

?>
person Bjorn    schedule 21.02.2011
comment
+1 Это исправляет мою текущую ситуацию, но я до сих пор не понимаю, почему он не использует свою собственную модель, которая уже делает это в фильтре beforeFind. Может быть, я должен задать это как отдельный вопрос, хотя. Спасибо. - person JD Isaacks; 22.02.2011

Лично я бы добавил условие в поисковый запрос для пользователей

$this->Users->find->('all',array('conditions'=>array('Address.deleted !='=>'1')));

(не проверял код на точный синтаксис, но это общая идея)

person Amy Anuszewski    schedule 21.02.2011
comment
Это дает мне эту ошибку: SQL Error: 1054: Unknown column 'Address.deleted' in 'where clause' Не знаю, почему, у меня есть удаленный столбец в таблице адресов. - person JD Isaacks; 22.02.2011
comment
Ваш режим отладки выше 0? Если это так, возьмите запрос из журнала запросов и вставьте его сюда, пожалуйста. - person Amy Anuszewski; 22.02.2011
comment
Вот запрос: SELECT User.id, User.first_name, User.last_name, User.password, User.email, User.role, WishList.id, WishList.user_id FROM users AS User LEFT JOIN wish_lists AS WishList ON (WishList.user_id = User.id) WHERE User.id = 4 AND Address.deleted != 1 LIMIT 1 Не похоже, что он выбран из таблицы адресов. Не уверен, как он получает данные, но в моей пользовательской модели у меня есть var $hasMany = 'Address';, а в таблице адресов у меня есть user_id - person JD Isaacks; 22.02.2011
comment
Используете ли вы сдерживаемое поведение? - person Amy Anuszewski; 22.02.2011
comment
@amy нет, я не такой, а должен? - person JD Isaacks; 22.02.2011
comment
Containable — отличный инструмент, поскольку он помогает уменьшить размер запроса, когда вам не нужно извлекать все связанные модели. Я просто пытался убедиться, что вы случайно не исключили адреса в приведенном выше запросе. - person Amy Anuszewski; 23.02.2011

Когда вы используете $this->User->find(...) и включаете Addresses, вы увидите только срабатывание обратных вызовов модели User, потому что это модель, которую вы используете для управления поиском.

Вот почему вы должны использовать дополнительные условия в ассоциациях вашей модели пользователя, чтобы отфильтровать обратимо удаленные адреса.

Если бы обратные вызовы модели Address запускались во время каждого поиска в модели User, когда область рекурсии включала адреса, вы бы не могли контролировать, когда включать адреса с обратимым удалением, и могли бы возникнуть конфликты в функциональности и манипулировании параметрами с помощью этих обратных вызовов. Не говоря уже о серьезном влиянии на производительность.

person ianmjones    schedule 22.02.2011