🐕
Laravel Filamentで子テーブルに保存する
Laravel Filamentで管理画面を実装した際に、子テーブルに同時に保存する方法があるか調べてみました。
前提
今回は犬とその犬の画像を登録するフォームを作成します。
Filamentの導入は既に行っている前提で行います。
dogsテーブル
論理名 | 物理名 |
---|---|
ID | id |
犬の名前 | name |
作成日時 | created_at |
更新日時 | updated_at |
dog_imagesテーブル
論理名 | 物理名 |
---|---|
ID | id |
犬ID | dog_id |
並び順 | sort |
画像ファイルパス | image |
作成日時 | created_at |
更新日時 | updated_at |
やりたいこと
- dogsテーブルにレコードを新規作成・編集した際にdog_imagesテーブルにも登録されるようにする。
実装手順
実装方法は非常に簡単で、relationship()
を呼ぶだけでFilament側がdog_imagesテーブルに保存までしてくれます。
Resourceクラスにリレーション先のテーブル用の項目を追加する
- 予めModelクラスにリレーションメソッドを定義してください。
app/Models/Dog.php
public function dogImages(): HasMany
{
return $this->hasMany(DogImage::class);
}
- DogResourceクラスのform()でレコード登録時の項目を追加します。
- 複数登録できるよう
Repeater
を使い、その中のschemaに画像アップロード用のFileUpload
を使って項目を追加します。 - その後
relationship()
でリレーション先を指定します。
app\Filament\Resources\DogResource.php
class DogResource extends Resource
{
protected static ?string $model = Dog::class;
public static function form(Form $form): Form
{
return $form
->schema([
TextInput::make('name')
->label('犬の名前'),
// 追加
Repeater::make('images')
->relationship('dogImages') // Dog.phpに定義したリレーションメソッドを指定
->schema([
FileUpload::make('image')
->label('画像')
->directory('dogs'),
])
->reorderable()
->orderColumn('sort'),
]);
}
}
これだけでフォームに入力欄が表示され、設定した内容がdog_imagesテーブルに保存されます。
並び順も保存したい場合
- 画像を複数登録した際の並び順も子テーブルに保存したい場合、Repeaterに
reorderable()
とorderColumn()
を指定してください。 - orderColumnの引数に指定したカラムに自動的に並び順の番号を保存してくれます。
Discussion