Laravel Eloquent 方法 updateOrCreate 更新时超过执行时间

Posted

技术标签:

【中文标题】Laravel Eloquent 方法 updateOrCreate 更新时超过执行时间【英文标题】:Laravel Eloquent method updateOrCreate exceeds execution time when updating 【发布时间】:2019-08-05 03:20:21 【问题描述】:

所以问题是,当我尝试更新我的实体时,它发现它更新了它,但可能会陷入循环并且不会退出。当我检查数据库时,即使在我已过期的 60 秒执行时间之前,我更改的值也会更新。 如果我不断刷新(这就是它变得疯狂的地方),其他讲座的更新值在执行此循环时开始每秒发生变化。 创建时(没有找到条件上的id它没有问题地创建它)

我的讲座是这样的:

class Lecture extends Model

use Searchable;
use SoftDeletes;

protected $primaryKey = 'id';

protected $touches = ['themes', 'educationTypes', 'subjects'];


protected $fillable= [
    'name', 'description', 'user_id', 'field_id', 'approved'
];


public static function boot()

    parent::boot();

    static::saved(function ($model) 
        $model->themes->filter(function ($item) 
            return $item->shouldBeSearchable();
        )->searchable();
    );




public function user()
    return $this->belongsTo('App\User')->with('companies');


public function geographies()
    return $this->belongsToMany('App\Geography');


public function educationTypes()
    return $this->belongsToMany('App\EducationType', 'lecture_education_type')->withTimestamps();;


public function themes()
    return $this->belongsToMany('App\Theme','lecture_theme', 'lecture_id', 'theme_id')->withTimestamps();;


public function subjects()
    return $this->belongsToMany('App\Subject', 'lecture_subject')->withTimestamps();;


public function cases()
    return $this->belongsToMany(
        'App\CompanyCase' ,
        'case_company_lecture',
        'lecture_id',
        'case_id',
        'id',
        'id')->withTimestamps();


public function companies()
    return $this->belongsToMany(
        'App\Company' ,
        'case_company_lecture',
        'lecture_id',
        'company_id',
        'id',
        'id'
    );


public function field()
    return $this->belongsTo('App\Field');


public function toSearchableArray()

    $this->themes;
    $this->user;
    $this->educationTypes;
    $this->subjects;
    $this->geography;

    return $this->toArray();

 

这是控制器:

    public function storeLecture(Request $request) 
    $lecture_id = $request->get('lecture_id');

    // It gets stuck between the comments
    $lecture = Lecture::updateOrCreate(['id' => $lecture_id],
    [
        'name'=> request('name'),
        'description'=> request('description'),
        'user_id'=> request('user_id')]
    );
    // and doesn't update the themes, edu types subjects and etc.

    $company_id = $request->get('company_id');
    $company = Company::find(request('company_id'));
    $lecture->companies()->sync([$company->id]);

    $eduTypes= $request->get('education_types');
    $themes= $request->get('themes');
    $subjects = $request->get('subjects');
    $geographies = $request->get('geographies');

    $lecture->themes()->sync($themes);
    $lecture->educationTypes()->sync($eduTypes);
    $lecture->subjects()->sync($subjects);
    $lecture->geographies()->sync($geographies);

    $n1 = new Notification();
    $n1->send(request('user_id'), 1, 'new_lecture', $lecture->id);


    $user = User::where('id', $request->id)->first();
    $user_with_companies = $user->load('companies');
    $slug = $user_with_companies->companies->first()->slug;
    return response(['success' => true]);

这是发送请求的前端方法(在这之间我有一个中间件根据 this.selectedExpert.id 检查用户是否是管理员(可以创建讲座),这不会干扰)。

    createUpdateLecture() 
  const url = `$window.location.origin/lecture/create/$
    this.selectedExpert.id
  `;
  this.$http
    .post(url, 
      education_types: this.allEducationTypes
        .filter(el => el.checked)
        .map(a => a.id),
      themes: this.allThemes.filter(el => el.checked).map(a => a.id),
      geographies: this.allGeographies
        .filter(el => el.checked)
        .map(a => a.id),
      subjects: this.allSubjects.filter(el => el.checked).map(a => a.id),
      name: this.lecture.name,
      description: this.lecture.description,
      user_id: this.selectedExpert.id,
      company_id: this.company.id,
      lecture_id: this.lecture.id
    )
    .then(res => 
      console.log(res);
      this.$parent.showLectureCreateModal = false;
      // window.location.reload();
    );

正如我所看到的那样,我可能真的很糟糕地使用了该方法,但我只是想更好地理解它以供进一步使用。

【问题讨论】:

【参考方案1】:

经过几天的研究和测试,结果发现 不是 updateOrCreate 方法导致了问题,因为我尝试了两个不同的创建和更新函数,但更新函数仍然有同样的问题。

这个问题是由Algolia创建的,它用于根据平台中的不同字段进行搜索。外汇。在主题中

class Theme extends Model

use SoftDeletes;

use Searchable;
protected $touches = ['lectures'];

public  function lectures()
    return $this->belongsToMany('App\Lecture');


public function toSearchableArray()

    $this->lectures;
    return $this->toArray();


从模型中删除可搜索的就行了!

【讨论】:

以上是关于Laravel Eloquent 方法 updateOrCreate 更新时超过执行时间的主要内容,如果未能解决你的问题,请参考以下文章

如何更新 Laravel Eloquent 管理的时间戳(created_at 和 updated_at)的时区?

laravel transaction : laravel 的事务是不支持eloquent的, 要用DB::的方式

laravel5.8之模型操作数据库 — Eloquent ORM(实践)

禁用 Laravel 的 Eloquent 时间戳

Laravel Eloquent 关系 keyBy()

Laravel eloquent 使用关系列更新列