Можно ли обновить пользователя, не касаясь временных меток?
Я не хочу полностью отключать отметки времени.
grtz
Можно ли обновить пользователя, не касаясь временных меток?
Я не хочу полностью отключать отметки времени.
grtz
Отключить его временно:
$user = User::find(1);
$user->timestamps = false;
$user->age = 72;
$user->save();
Вы можете дополнительно включить их после сохранения.
Это только функция Laravel 4 и 5 и не относится к Laravel 3.
В Laravel 5.2
вы можете установить общедоступное поле $timestamps
на false
следующим образом:
$user->timestamps = false;
$user->name = 'new name';
$user->save();
Или вы можете передать параметры в качестве параметра функции save()
:
$user->name = 'new name';
$user->save(['timestamps' => false]);
Для более глубокого понимания того, как это работает, вы можете взглянуть на класс \Illuminate\Database\Eloquent\Model
в методе performUpdate(Builder $query, array $options = [])
:
protected function performUpdate(Builder $query, array $options = [])
// [...]
// First we need to create a fresh query instance and touch the creation and
// update timestamp on the model which are maintained by us for developer
// convenience. Then we will just continue saving the model instances.
if ($this->timestamps && Arr::get($options, 'timestamps', true)) {
$this->updateTimestamps();
}
// [...]
Поля timestamps обновляются только в том случае, если общедоступное свойство timestamps
равно true
или Arr::get($options, 'timestamps', true)
возвращает true
(что делает это по умолчанию, если массив $options
не содержит ключа timestamps
).
Как только один из этих двух возвращает false
, поля timestamps
не обновляются.
Чтобы добавить к Антонио Карлосу Рибейру ответ
Если вашему коду требуется деактивация временных меток более 50% времени - возможно, вам следует отключить автоматическое обновление и вручную получить к нему доступ.
Вкратце, когда вы расширяете красноречивую модель, вы можете отключить метку времени, поставив
UPDATE
public $timestamps = false;
внутри вашей модели.
Над образцами работает классно, но только для одного объекта (только одна строка за раз).
Это простой способ временного отключения временных меток, если вы хотите обновить всю коллекцию.
class Order extends Model
{
....
public function scopeWithoutTimestamps()
{
$this->timestamps = false;
return $this;
}
}
Теперь вы можете просто вызвать что-то вроде этого:
Order::withoutTimestamps()->leftJoin('customer_products','customer_products.order_id','=','orders.order_id')->update(array('orders.customer_product_id' => \DB::raw('customer_products.id')));
Для пользователей Laravel 5.x, которые пытаются выполнить вызов Model::update()
, чтобы заставить его работать, вы можете использовать
Model::where('example', $data)
->update([
'firstValue' => $newValue,
'updatedAt' => \DB::raw('updatedAt')
]);
Поскольку функция Model :: update больше не принимает второй аргумент. ref: laravel 5.0 api
Протестировано и работает на версии 5.2.
Если вам нужно обновить запросы одиночной модели:
$product->timestamps = false;
$product->save();
или
$product->save(['timestamps' => false]);
Если вам нужно обновить несколько моделей, используйте
DB::table('products')->...->update(...)
вместо
Product::...->update(...)
Я столкнулся с ситуацией необходимости массового обновления, которое включает в себя объединение, поэтому updated_at
вызывало повторяющиеся конфликты столбцов. Я исправил его с помощью этого кода, не требуя области:
$query->where(function (\Illuminate\Database\Eloquent\Builder $query) {
$query->getModel()->timestamps = false;
})
Вы также можете использовать этот синтаксис:
Model::where('Y', 'X')
->update(['Y' => 'Z'], ['timestamps' => false]);
Я решил это по-своему, не играя ни с какими конфигами (не лучшим способом, но полезным):
$time = $user->updated_at; //write a copy of "updated_at" to $time variable
//do anything you want and let timestamp work as normal
$user->update('updated_at'=> $time) //At the end, rewrite the $time to "updated_at"
Не забудьте сделать updated_at
fillable
в вашей модели.