#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.02. можете ли вы опубликовать соответствующий пример кода вашего контроллера 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