Настройка функции beforeFind() в AppModel

#cakephp #cakephp-2.0

#cakephp #cakephp-2.0

Вопрос:

У меня есть status_id поле во всем, которое управляет публикацией данных и т.д. Я создал это в своей AppModel, чтобы позаботиться обо всей фильтрации.

 public function beforeFind($queryData) {
        // Force all finds to only find stuff which is live
        $queryData['conditions'][$this->alias.'.status_id'] = 1;
        return $queryData;
}
  

Который работает нормально, пока вы не перейдете в маршрутизацию администратора, в этот момент вы хотите увидеть все элементы, и они фильтруются. Есть ли способ узнать, используете ли вы маршрутизацию администратора из AppModel?

Ответ №1:

У меня есть опыт в аналогичной ситуации, когда я использую поведение «мягкого удаления».

Моя рекомендация — проверить, есть ли у вас уже условие в status_id поле, и устанавливать его только в том случае, если у вас его нет. Вот так:

 public function beforeFind($queryData) {
    if (! isset($queryData['conditions'][$this->alias.'.status_id'])) {
        // Force all finds to only find stuff which is live
        $queryData['conditions'][$this->alias.'.status_id'] = 1;
    } elseif ($queryData['conditions'][$this->alias.'.status_id'] == 'all') {
        unset($queryData['conditions'][$this->alias.'.status_id']);
    }
    return $queryData;
}
  

Таким образом, у вас есть желаемая функциональность по умолчанию, и вы также можете использовать обычные условия в status_id поле, когда это необходимо.
В качестве бонуса, чтобы игнорировать условие, как вы хотите в маршрутизации администратора, вы можете использовать это:

     $data = $this->paginate('YourModel', array('YourModel.status_id' => 'all'));
  

По сути, это просто удобство, позволяющее избежать необходимости передавать все идентификаторы статуса как условие «подделки».

Вот как я бы это сделал. Надеюсь, это поможет.

Ответ №2:

Вы можете проверить маршрут администратора в своем контроллере и определить его следующим образом:

 App Controller:

if(isAdmin){
$queryData['conditions']['isAdmin'] = true;
}

In your AppModel:

if(!isset($queryData['conditions']['isAdmin'] amp; $queryData['conditions']['isAdmin'] !== true )){
$queryData['conditions'][$this->alias.'.status_id'] = 1;
        return $queryData;

} else {
       return $queryData
}
  

Это грязный способ, но он должен работать.

Комментарии:

1. Notice (8): Indirect modification of overloaded property QuicklinksController::$queryData has no effect [APPControllerAppController.php, line 9] Я должен упомянуть, что я в Cake2.0

2. можете ли вы опубликовать соответствующий пример кода вашего контроллера quicklinks?

3. Вот где ваше решение! 😉

4. Я думаю, это потому, что конструкция условий в 2.0 отличается от 1.3, аналогично тому, $this->data как сейчас $this->request->data

Ответ №3:

у модели нет причин знать, что такое маршрут. Его цель — передать контроллеру запрошенное. Другими словами, вы должны установить условие в контроллере, а не в модели.

Извините, что был слишком краток.

То, что вы пытаетесь сделать, противоречит шаблону проектирования MVC. Это контроллер, который обрабатывает и направляет запросы, сделанные клиентом.

 In your controller:
function index(){
    $data = $this->paginate('YourModel', array('YourModel.status_id' => 1));
    $this->set('data', $data);
}

function admin_index(){
    $data = $this->paginate();
    $this->set('data', $data);
}
  

Еще менее подробный

Вы пытаетесь определить в модели, был ли сделан запрос из маршрутизации администратора, что является неправильным путем. Контроллер обрабатывает это автоматически. admin_index() обрабатывает запрос индекса, сделанный по маршруту администратора, запрос index(), сделанный по обычному маршруту.

Именно в контроллере вы решаете, какие данные вы хотите. Вы должны перенести логику, которая есть в вашем методе beforeFind, в ваш контроллер, как в примере выше.

Комментарии:

1. Был бы полезен более подробный ответ. Поскольку настройка свойств модели в контроллере приложения работает в определенной степени, но она настолько надежна.

2. извините за это, смотрите изменения в моем ответе

3. Я думаю, вы неправильно поняли вопрос. beforeFind() выполняется в модели перед выполнением вызова find. Этот вызов поиска выполняется с контроллера. Итак, это за контроллером.

4. Думаю, я понял ваш вопрос. Вы пытаетесь определить в модели, был ли сделан запрос из маршрутизации администратора, что является неправильным путем. Смотрите мою правку

5. Я не хочу вставлять одну и ту же функцию в каждый отдельный контроллер. Я думаю, я могу переместить его в AppControllers beforeFilter() , и тогда я потеряю beforeFind()

Ответ №4:

Ответ, который я получил, заключался бы в том, чтобы установить маршрут в качестве атрибута в модели с контроллера, который затем вы можете проверить из модели.

Однако у CakeDC есть пакет плагинов Utils, который включает в себя поведение SoftDeletable, которое я использую сейчас. https://github.com/cakedc/utils