Модель CakePHP с «Между датами» - PullRequest
5 голосов
/ 25 августа 2009

У меня большой набор данных (более миллиарда строк). Данные разделены в базе данных по дате. Таким образом, мой инструмент запросов ДОЛЖЕН указывать условие SQL между каждым запросом, иначе ему придется сканировать каждый раздел ... и, ну, он истечет время ожидания, прежде чем он когда-либо вернется.

Итак ... мой вопрос, поле в разбитой на части базе данных является датой ..

Используя CakePHP, как я могу указать даты "между" в моей форме?

Я думал о том, чтобы сделать "start_date" и "end_date" в самой форме, но это может поставить меня перед вторым вопросом ... как мне проверить это в модели, которая связана с таблицей?

Ответы [ 3 ]

8 голосов
/ 26 августа 2009

Если я правильно следую за вами:

  • Пользователь должен указать даты начала / окончания для запросов на поиск, сгенерированных из формы
  • Вам необходимо проверить эти даты, чтобы, например:
    • дата окончания после даты начала
    • дата окончания не через столетия от даты начала
  • Вы хотите, чтобы ошибки проверки появлялись внутри формы (даже если это не сохранение)

Поскольку вы хотите проверить эти даты, их будет сложнее получить, когда они спрятаны в вашем массиве условий. Я предлагаю попробовать передать их по отдельности, а затем разобраться с ними позже:

$this->Model->find('all', array(
    'conditions' => array(/* normal conditions here */),
    'dateRange' => array(
        'start' => /* start_date value */,
        'end'   => /* end_date value */,
    ),
));

Надеемся, что вы сможете обрабатывать все остальное в beforeFind фильтре:

public function beforeFind() {
    // perform query validation
    if ($queryData['dateRange']['end'] < $queryData['dateRange']['start']) {
        $this->invalidate(
            /* end_date field name */,
            "End date must be after start date"
        );
        return false;
    }
    /* repeat for other validation */
    // add between condition to query
    $queryData['conditions'][] = array(
        'Model.dateField BETWEEN ? AND ?' => array(
            $queryData['dateRange']['start'],
            $queryData['dateRange']['end'],
        ),
    );
    unset($queryData['dateRange']);
    // proceed with find
    return true;
}

Я не пробовал использовать Model::invalidate() во время операции поиска, поэтому это может даже не сработать. Идея состоит в том, что если форма создается с использованием FormHelper, эти сообщения должны вернуться к полям формы.

В противном случае вам может потребоваться выполнить эту проверку в контроллере и использовать Session::setFlash(). если это так, вы также можете избавиться от beforeFind и вставить массив условий BETWEEN с другими вашими условиями.

1 голос
/ 05 марта 2013

, если вы хотите найти данные за последние 20 дней.

    $this->loadModel('User');
    //$this->User->recursive=-1;
    $data=$this->User->find('all', array('recursive' => 0,
   'fields' => array('Profile.last_name','Profile.first_name'),'limit' => 20,'order' => array('User.created DESC')));

другое время между двумя датами

$start = date('Y-m-d') ;
        $end = date('Y-m-d', strtotime('-20 day'));
        $conditions = array('User.created' =>array('Between',$start,$end));
        $this->User->find("all",$conditions)
0 голосов
/ 26 августа 2009

Вы можете написать собственный метод в вашей модели для поиска между датами:

function findByDateRange($start,$end){
    return $this->find('all',array('date >= '.$start,'data >= .'$end));
}

Что касается проверки, вы можете использовать обратный вызов beforeValidate() модели для проверки двух дат. Подробнее об этом здесь .

function beforeValidate(){
    if(Validation::date($this->data['Model']['start_date'])){
        return false;
    }
    if(Validation::date($this->data['Model']['end_date'])){
        return false;
    }
    return parent::beforeValidate();
}

Это отвечает на ваш вопрос?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...