Я хочу обновить дату до следующего дня. Как мне это сделать?
Теперь делаю это с помощью этого.
$calendar = Calendar::find($id);
$calendar->update(['started_at' => $calendar->started_at->addDay(1)));
или я могу это сделать
$calendar->started_at->addDay(1);
$calendar->save();
Но для меня это решение плохо, потому что есть 2 запроса в базе данных. Я не буду делать это по одному запросу.
Есть ли способ динамически обновить дату до даты следующего дня?
Например
Calendar::where('id', $id)->updateToNextDay('started_at');
Я также нахожу эквивалент sql
UPDATE `calendar` SET `started_at` = `started_at` - INTERVAL 1 DAY;
Спасибо за внимание.
Вы также можете создать функцию в модели Calendar для добавления дня.
Первое решение плохое, потому что оно выполняет 2 запроса в базе данных






Вы можете написать свой собственный метод в модели календаря, например,
public function updateToNextDay(string $column)
{
$this->update([
$column => \Db::raw("$column + INTERVAL DAY 1");
]);
}
Не проверял, но работать должно.
Это два запроса в БД. Я не буду делать это по одному запросу
@Davit Какой тип данных у вашего столбца start_at?
дата и время. Я нахожу sql-эквивалент ОБНОВЛЕНИЕ calendar НАБОР started_at = started_at - ИНТЕРВАЛ 1 ДЕНЬ;
Проверьте DB :: raw, проверьте необработанный запрос.
Обновленный ответ также не завершит то, что они хотят, поскольку, чтобы добраться до этого момента, вы уже связались бы с базой данных и получили модель.
Я могу сделать это с помощью DB :: raw, но для меня приоритетное использование красноречивой модели, а затем фасада DB
@Davit, я не думаю, что вы понимаете, что такое модель Eloquent. Чтобы использовать саму модель, вам нужно будет выбрать данные из базы данных, как работает ORM. В противном случае вы просто используете Query Builder. DB :: raw () просто форматирует необработанное выражение, оно может использоваться либо моделью, либо построителем запросов.
Чувак, основная идея Model - получить модель и затем обновить, это тоже помогает с коллекциями. Поскольку вам не нужны два запроса, вы должны действовать грубо и грубо.
Я могу сделать это для того же метода красноречивого публичная функция newEloquentBuilder ($ query) {возвращает новый ExtendedBuilder ($ query); } и добавить в ExtendedBuilder метод updateToNextDay ()
@Devon Он работает с фасадом, метод не статичен, но да, будет только один вызов обновления, так как экземпляр объекта модели.
Это должно работать
Calendar::where('id', $id)->update([
'started_at' => DB::raw("DATE_ADD(started_at, INTERVAL 1 DAY)")
]);
Дай мне знать :)
результат date_add () ожидает, что параметр 1 будет DateTime, заданная строка
Какой тип данных у started_at?
@Davit Обновил мой ответ. Проверь сейчас.
Вызов неопределенной функции CalendarServices \ STR_TO_DATE ()
@Davit Мне не хватало строковых обозначений в DB :: Raw. LOL Sry. Должно работать сейчас.
Это тоже SQLSTATE [42000]: синтаксическая ошибка или нарушение прав доступа: 1064 У вас есть ошибка в синтаксисе SQL;
@Davit Окончательный ответ. Проверь сейчас.
Я также пытаюсь ответить @Devon, и это решает мою проблему. За ваши усилия, чтобы помочь мне проголосовать. Спасибо
@Davit Да, все в порядке. Не волнуйтесь. Ваша проблема решена, поэтому недурно
$startDate = date_timestamp_get($calendar->started_at);
$date = date('Y-m-d H:i:s', strtotime('+1 day', $startDate));
$calendar->update(['started_at' => $date]);
Calendar::where('id', $id)->update() - это просто синтаксический сахар. Это приведет вас к построителю запросов и аналогично запуску DB::table('calendar')->where('id', $id)->update();.
Сила модели в ORM заключается в получении данных из базы данных, сопоставлении их со свойствами объекта и последующем манипулировании этим объектом. Накладные расходы на один выбор обновления довольно малы, и если вы беспокоитесь об этих накладных расходах на этапе разработки, вы, вероятно, слишком оптимизировали.
Если вы хотите отказаться от выбора, вы можете использовать построитель запросов с необработанным выражением SQL. Любой из них вызовет построитель запросов и выполнит тот же точный запрос:
Calendar::where('id', $id)
->update(['started_at' => DB::raw("started_at + INTERVAL 1 DAY")]);
или же
DB::table('calendars')->where('id', $id)
->update(['started_at' => DB::raw("started_at + INTERVAL 1 DAY")]);
Первый результат решения - SQLSTATE [42000]: синтаксическая ошибка или нарушение прав доступа: 1064 У вас есть ошибка в синтаксисе SQL; ....., и я не буду использовать красноречивую модель без фасада БД.
@Davit Прочтите, что я написал, они оба делают одно и то же.
Поменяли местами 1 и день, они были в неправильном порядке.
В вашем ответе подробно объясняется, что сделано в Laravel. За объяснение проголосуйте за. но это не решение моего ответа
Я обновил ваш ответ для использования красноречивых модельных функций. Если вы предложите мне подтвердить это,
Это не сработает, потому что вы не внутри экземпляра. Когда вы используете Calendar::where(), вы не возвращаете экземпляр Calendar, вы возвращаете экземпляр Eloquent Builder. Вы также должны быть осторожны, помещая переменные непосредственно в необработанное выражение, если они когда-либо были получены путем ввода пользователем, вы подвергнетесь атаке с помощью инъекции.
Хорошо, я забыл об инъекционной атаке
Что не так с первым решением? И нет, встроенного способа сделать это из коробки нет. Вы можете расширить конструктор запросов и добавить его самостоятельно, но это очень грязный прием ...