最近在做文章浏览量自增的时候,总是会自动更新 updated_at 字段:

$article->increment('views', 1);

上面的用法会自动更新updated_at,如何避免了?

查看了下源码,发现更新的时候会调用 usesTimestamps()方法判断是否更新updated_at

    // vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php

    /**
     * Add the "updated at" column to an array of values.
     *
     * @param  array  $values
     * @return array
     */
    protected function addUpdatedAtColumn(array $values)
    {
        if (! $this->model->usesTimestamps() ||
            is_null($this->model->getUpdatedAtColumn())) {
            return $values;
        }

        $column = $this->model->getUpdatedAtColumn();

        $values = array_merge(
            [$column => $this->model->freshTimestampString()],
            $values
        );

        $segments = preg_split('/\s+as\s+/i', $this->query->from);

        $qualifiedColumn = end($segments).'.'.$column;

        $values[$qualifiedColumn] = $values[$column];

        unset($values[$column]);

        return $values;
    }

usesTimestamps() 则是依据timestamps 属性:

    /**
     * Determine if the model uses timestamps.
     *
     * @return bool
     */
    public function usesTimestamps()
    {
        return $this->timestamps;
    }

所以,这里只需要控制timestamps的值即可,创建一个trait:

<?php

namespace App\Traits;

trait UpdateWithoutUsesTimestamps
{
    /**
     * Determine if the model uses timestamps.
     */
    public function notUsesTimestamps()
    {
        $this->timestamps = false;

        return $this;
    }
}

然后在Model 中引入UpdateWithoutUsesTimestamps:

<?php

namespace App;

use App\Traits\UpdateWithoutUsesTimestamps;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    use UpdateWithoutUsesTimestamps;
}

然后,在自增的时候这样使用:

$article->notUsesTimestamps()->increment('views', 1);