首页 > 解决方案 > Eloquent 模型上的 $touches 属性确实减慢了测试速度

问题描述

描述:

我是否正在从事一个项目,该项目主要由我使用很久以前从这篇Laravel 模型缓存belongsTo中学到的技巧缓存的关系组成。现在的问题是当我运行测试时 PHPUnit 冻结或者可能需要很长时间才能运行单个测试,因为我等了一个多小时,但是如果我评论该属性,测试运行得很好。现在,每次我想测试时,我都无法注释掉所有模型中的所有属性,所以我的问题是,我该怎么办,是否可以在测试期间将其关闭?hasMany$touches$touches

重现步骤:

模型

<?php

namespace App;

use App\Contracts\CacheableModelInterface;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Country extends Model implements CacheableModelInterface
{
    use Searchable,
        Concerns\HasSlug,
        Concerns\HasCache,
        Concerns\HasManyRegions,
        Concerns\HasManyProvinces,
        Concerns\HasManyLocalGovernmentAreas,
        Concerns\HasManyCities,
        Concerns\HasManyVillages;

    /**
     * The relationships that should be touched on save.
     *
     * @var array
     */
    protected $touches = ['regions', 'provinces', 'localGovernmentAreas', 'cities', 'villages'];

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'longitude', 'latitude', 'iso_code', 'calling_code'
    ];

    /**
     * Get the indexable data array for the model.
     *
     * @return array
     */
    public function toSearchableArray()
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
        ];
    }
}

存储库


public function getRelationshipBelongingTo(string $name, string $relationship)
{
    return ($this->model->where("name->".app()->getLocale(), $name)
                        ->firstOrFail())
                        ->{$relationship};
}

控制器

// CountryController.php
...
public function provinces(string $locale, string $name)
{
    try {
        $this->checkLocale($locale);

        app()->setLocale($locale);

        $provinces = $this->repository
            ->getRelationshipBelongingTo($name, 'cached_provinces');

        return response()->json([
            'success'       => true,
            'provinces'       => new ProvinceCollection($provinces)
        ]);

    } catch (ModelNotFoundException $exception) {

        return response()->json([
            'success'       => false,
            'message'       => "No country named '{$name}' was found in the {$this->localeFullName($locale)} database."
        ]);

    } catch (InvalidLocaleException $exception) {

        return response()->json([
            'success'       => false,
            'message'       => $exception->getMessage()
        ]);
    }
}

测试

/**
 * @test
 */
public function can_return_provinces_belonging_to_country()
{
    $country = $this->createCountry();

    // Region is going to be needed in the factory when creating Province
    // files so we need to have at least one present.
    factory(\App\Region::class, 1)->create();

    $provinces = $country->provinces()->saveMany(factory(\App\Province::class, 3)->make());

    $response = $this->getJson($this->route."/{$country->name}/provinces");

    $response->assertJsonStructure([
        'success', 'provinces'
    ]);

    $responseProvinces = $response->json('provinces');

    $this->assertEquals($provinces->count(), collect($responseProvinces)->count());

    $response->assertOk();
}

标签: phplaraveleloquent

解决方案


推荐阅读