我需要帮助理解为什么来自
afterStateUpdated
挂钩的计算字段没有发送到数据库。
我正在开发一个有歌词的网站。后端管理员使用 Filament 3.x 并且工作正常。我正在努力添加附加可以嵌入歌词页面的在线媒体(例如 YouTube 视频)的功能。我想要在管理中的功能是简单地输入 youtube URL 并使用
MediaService
与第 3 方库,解析 URL,从 YouTube 获取视频标题和其他元数据等。在灯丝 afterStateUpdated
钩子中.
但是,当我尝试创建并保存到数据库时,出现错误,表明只有
updated_at
和 created_at
被发送到数据库,并出现以下错误:
SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: media.host (Connection: sqlite, SQL: insert into "media" ("updated_at", "created_at") values (2024-06-18 15:55:09, 2024-06-18 15:55:09))
这是
Media
模型:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Media extends Model
{
use HasFactory;
protected $fillable = ['host', 'media_id', 'url', 'title'];
}
这是
media
表的迁移:
public function up(): void
{
Schema::create('media', function (Blueprint $table) {
$table->id();
$table->foreignId('song_id')
->nullable()
->constrained()->
onDelete('cascade');
$table->string('host');
$table->string('media_id');
$table->string('title')->nullable();
$table->string('url')->nullable();
$table->timestamps();
});
}
还有来自灯丝的
form
MediaResource
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('input_url')
->label('Media URL')
->live(onBlur: true)
->afterStateUpdated(function (Forms\Set $set, $state) {
$mediaService = new MediaService();
$parsed = $mediaService->parseUrl($state);
if ($parsed) {
$set('title', $parsed['title']);
$set('host', $parsed['host']);
$set('media_id', $parsed['media_id']);
$set('url', $parsed['url']);
}
}),
Forms\Components\TextInput::make('title')
->required()
->disabled(),
Forms\Components\TextInput::make('host')
->required()
->disabled(),
Forms\Components\TextInput::make('media_id')
->required()
->disabled(),
Forms\Components\TextInput::make('url')
->required()
->disabled(),
]);
}
我通过更彻底地阅读文档自己解决了这个问题。使用
disabled()
属性实际上会阻止数据发送到服务器。但是,有一个 readOnly()
属性允许将数据发送到服务器,即使您无法在表单中对其进行编辑。
对于后代,这里是表单的最终代码:
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('input_url')
->label('Media URL')
->live(onBlur: true)
->afterStateUpdated(function (Forms\Set $set, $state, Forms\Components\TextInput $component) {
$mediaService = new MediaService();
$parsed = $mediaService->parseUrl($state);
if ($parsed) {
$set('title', $parsed['title']);
$set('host', $parsed['host']);
$set('media_id', $parsed['media_id']);
$set('url', $parsed['url']);
}
}),
Forms\Components\TextInput::make('title')
->required()
->readOnly(),
Forms\Components\TextInput::make('host')
->required()
->readOnly(),
Forms\Components\TextInput::make('media_id')
->required()
->readOnly(),
Forms\Components\TextInput::make('url')
->required()
->readOnly(),
]);
}