问题描述
我有一个 Trait
,我在应用中的多个模型上使用它来在模型上设置 UUID
:
<?PHP
namespace App\Traits;
use Illuminate\Support\Str;
trait UsesUuid
{
protected static function bootUsesUuid()
{
static::creating(function ($model) {
if (!$model->uuid) {
$model->uuid = (string) Str::orderedUuid();
}
});
}
}
正常使用应用程序时它工作正常,但是当我尝试编写测试以通过 post
route
创建模型并转储 response
我得到一个 {{1} } Integrity constraint violation: 19 NOT NULL constraint Failed: venues.uuid
错误。
我正在做的测试的一个例子是:
500
我迁移中的列是 public function testOwnerCanSuccessfullyCreateVenue()
{
$amenity = Amenity::inRandomOrder()->pluck('id')->first();
$response = $this->actingAs($this->createdUser('owner'))->post(route('venues.store'),[
"name" => "create-name","address_line_1" => "create-address_line_1","address_line_2" => "create-address_line_2","county" => "create-county","postcode" => "create-postcode","phone_number" => "create-phone_number","notes" => "create-notes","amenities" => [$amenity]
]);
dd($response);
}
其他一切都运行良好,但我是编写测试的新手,不知道如何解决这个问题。
我使用 Trait 的原因是为了避免在持久化到数据库时概述所有列值,因为我使用 $table->uuid('uuid')->unique();
来填充模型:
$request->validated()
很明显,因为 UUID 没有在这里设置,它是由一个 Trait 完成的,它没有通过测试。如果我删除 Trait 并执行以下操作,我可以让测试通过并让应用程序仍然工作:
$venue = Venue::create($request->validated());
这很好,我可以接受,但我想更多地了解 Trait 没有触发的原因以及如何绕过它。
编辑: 只是根据下面的答案添加更多内容,正确定义了可填写字段:
$venue = Venue::create(
$request->validated() + ['uuid' => Str::orderedUuid()]
);
解决方法
我认为这是模型的问题。 Venue
模型应使用 protected $fillable = ['uuid'];
。
Laravel 默认保护质量分配。如果您在创建模型上提供数组,Laravel 不允许这样做。您需要提供一个受保护的可填充数组,因此laravel 只能为这些字段解锁。