о безжировом фреймворке

У меня такая странность с запросом на обновление в безжировых фреймворках

public function updateTransactionSalesFlush() {

    $this->load(array('active=1 AND void=0'));
    if (!$this->dry()) {            
        $data = array('salestemp' => 0);
        $this->copyFrom($data);
        $this->update();            
    }
}

Эта функция обновляет только первую запись из выбранных, но не все, как ожидалось. Я что-то не так делаю или это баг??

Следующий запрос отлично работает с использованием функции exec:

 UPDATE transactions SET salestemp=0 WHERE active= 1 AND void= 0

person andymo    schedule 04.10.2017    source источник


Ответы (2)


https://fatfreeframework.com/3.6/databases

По умолчанию метод load() преобразователя данных извлекает только первую запись, которая соответствует указанным критериям. Если у вас есть несколько записей, соответствующих тому же условию, что и первая загруженная запись, вы можете использовать метод skip() для навигации:

person ceejayoz    schedule 04.10.2017
comment
спасибо, теперь все ясно, но перебирать все записи с помощью метода skip() для обновления кажется очень бесполезным. Гораздо лучше использовать метод exec() или нет?? - person andymo; 04.10.2017

Метод load() загружает все записи, соответствующие указанным критериям, но сопоставляет только одну запись за раз.

Затем вам нужно использовать методы next() или skip() для навигации по набору записей.

Ваш код обновляет только первую запись, потому что в ней отсутствует цикл. Вот как это исправить:

public function updateTransactionSalesFlush() {

    $this->load(array('active=1 AND void=0'));
    while (!$this->dry()) {
        $this->salestemp=0;
        $this->update();
        $this->next();
    }
}

В качестве альтернативы вы можете вызвать метод find() вместо load():

public function updateTransactionSalesFlush() {

    $records=$this->find(['active=1 AND void=0']);
    foreach ($records as $record) {
        $record->salestemp=0;
        $record->update();
    }
}

Конечно, если вы обновляете большое количество записей, вам лучше выполнить один оператор UPDATE через метод exec():

public function updateTransactionSalesFlush() {

    $this->db->exec('UPDATE '.$this->table.' SET salestemp=0 WHERE active=1 AND void=0');
}
person xfra35    schedule 05.10.2017
comment
Это может быть хорошей идеей для улучшения. Метод update может дополнительно принимать фильтр, как и метод remove. - person george007; 05.10.2017
comment
Тогда потребуются два аргумента: фильтр и пары ключ/значение. - person xfra35; 05.10.2017
comment
Сначала я думал использовать свойства объекта как пары ключ/значение, но это может быть не всегда интуитивно понятно, и это не будет работать с такими выражениями, как key1=key2+1. Так что, как бы я ни ненавидел идею ванильного SQL, я должен согласиться с тем, что это слишком сложно сделать с помощью картографа данных. - person george007; 06.10.2017