web-dev-qa-db-fra.com

Mettre à jour sans toucher aux horodatages (Laravel)

Est-il possible de mettre à jour un utilisateur sans toucher aux horodatages?

Je ne veux pas désactiver complètement les horodatages ..

grtz

53
Jannick Vandaele

Désactivez-le temporairement:

$user = User::find(1);
$user->timestamps = false;
$user->age = 72;
$user->save();

Vous pouvez éventuellement les réactiver après l'enregistrement.

Ceci est une fonctionnalité Laravel 4 et 5 uniquement et ne s'applique pas à Laravel 3.

131

Dans Laravel 5.2, Vous pouvez définir le champ public $timestamps Sur false comme ceci:

$user->timestamps = false;
$user->name = 'new name';
$user->save();

Ou vous pouvez passer les options en tant que paramètre de la fonction save():

$user->name = 'new name';
$user->save(['timestamps' => false]);

Pour une compréhension plus approfondie de son fonctionnement, vous pouvez jeter un œil à la classe \Illuminate\Database\Eloquent\Model, Dans la méthode 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();
    }

    // [...]

Les champs d'horodatage sont mis à jour uniquement si la propriété publique timestamps est égale à true ou Arr::get($options, 'timestamps', true) renvoie true (ce qu'elle fait par défaut si le $options le tableau ne contient pas la clé timestamps).

Dès que l'un de ces deux renvoie false, les champs timestamps ne sont pas mis à jour.

18
Mike

Pour ajouter à la réponse d'Antonio Carlos Ribeiro

Si votre code nécessite une désactivation des horodatages plus de 50% du temps - vous devriez peut-être désactiver la mise à jour automatique et y accéder manuellement.

Dans éloquent lorsque vous étendez le modèle éloquent, vous pouvez désactiver l'horodatage en mettant

MISE À JOUR

public $timestamps = false;

à l'intérieur de votre modèle.

14
azngunit81

Les exemples ci-dessus fonctionnent bien, mais uniquement pour un seul objet (une seule ligne à la fois).

C'est un moyen simple de désactiver temporairement les horodatages si vous souhaitez mettre à jour toute la collection.

class Order extends Model
{

 ....

    public function scopeWithoutTimestamps()
    {
        $this->timestamps = false;
        return $this;
    }

}

Maintenant, vous pouvez simplement appeler quelque chose comme ceci:

Order::withoutTimestamps()->leftJoin('customer_products','customer_products.order_id','=','orders.order_id')->update(array('orders.customer_product_id' => \DB::raw('customer_products.id')));
14
Maksim Martianov

Pour les utilisateurs Laravel 5.x qui tentent d'effectuer un appel Model::update(), pour le faire fonctionner, vous pouvez utiliser

Model::where('example', $data)
     ->update([
       'firstValue' => $newValue,
       'updatedAt' => \DB::raw('updatedAt')
     ]);

Comme la fonction Model :: update ne prend plus de second argument. ref: laravel 5.0 api

Testé et fonctionne sur la version 5.2.

7
hilnius

Si vous devez mettre à jour modèle unique requêtes:

$product->timestamps = false;
$product->save();

ou

$product->save(['timestamps' => false]);

Si vous devez mettre à jour modèle multiple les requêtes utilisent

DB::table('products')->...->update(...)

au lieu de

Product::...->update(...)
4
Luca C.

Je suis tombé sur la situation d'avoir besoin de faire une mise à jour de masse qui implique une jointure, donc updated_at provoquait des conflits de colonnes en double. Je l'ai corrigé avec ce code sans avoir besoin d'une portée:

$query->where(function (\Illuminate\Database\Eloquent\Builder $query) {
    $query->getModel()->timestamps = false;
})
3
Zane Hooper

Vous pouvez également utiliser cette syntaxe:

Model::where('Y', 'X')
    ->update(['Y' => 'Z'], ['timestamps' => false]);
2
Marek Skiba