Laravel 灯丝状态更新后。字段未保存到数据库

问题描述 投票:0回答:1

我需要帮助理解为什么来自

afterStateUpdated
挂钩的计算字段没有发送到数据库。

我正在开发一个有歌词的网站。后端管理员使用 Filament 3.x 并且工作正常。我正在努力添加附加可以嵌入歌词页面的在线媒体(例如 YouTube 视频)的功能。我想要在管理中的功能是简单地输入 youtube URL 并使用

MediaService
与第 3 方库,解析 URL,从 YouTube 获取视频标题和其他元数据等。在灯丝
afterStateUpdated
钩子中.

一切似乎都在发挥作用。 Filament create Media Form

但是,当我尝试创建并保存到数据库时,出现错误,表明只有

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(),
            ]);
    }
php laravel laravel-filament
1个回答
0
投票

我通过更彻底地阅读文档自己解决了这个问题。使用

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(),
            ]);
    }

© www.soinside.com 2019 - 2024. All rights reserved.