LoginSignup
4
2

More than 1 year has passed since last update.

【livewire2.0】プロパティにEloquentCollectionを使う際の注意点

Last updated at Posted at 2022-12-10

概要

livewireコンポーネント内のプロパティで使える型に、EloquenCollectionがあります。

通常のSupportCollectionは使えません

EloquentCollectionの便利な所は
内包しているEloquentモデルオブジェクトをlivewireが勝手に配列にしてしまわない所です。

基本的にモデルオブジェクトを内包した配列を生成した場合、モデルオブジェクトが全て配列に変換されてしまいます。

$this->hoge[] = User::find(1);

上記のように記述した場合、レンダリング時にUserモデルオブジェクトがただの配列になります。
EloquentCollectionなら特定のモデルオブジェクトを取り出した際に、モデルが持つ振る舞いを使用する事ができます。

ですが使用する際に注意点があります

永続化されてないモデルオブジェクトをpushするとエラーが発生する

以下のようなlivewireコンポーネントがあるとします

php側

<?php

namespace App\Http\Livewire;

use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
use Livewire\Component;

class Sample1202 extends Component
{
    public Collection $users;

    public function mount()
    {
        $this->users = User::all();
    }

    public function render()
    {
        return view('livewire.sample1202')
            ->extends('adminlte::page')
            ->section('content');
    }

    public function addUser()
    {
        $this->users->push(User::make([
            'name' => 'John Doe',
            'email' => 'john@example.com',
            'password' => 'password'
        ]));
    }
}

Blade側

<div>
    @foreach($users as $user)
        <p>id: {{ $user->id }}</p>
        <p>名前:{{ $user->name }}</p>
    @endforeach
    <button wire:click="addUser">追加</button>
</div>

DB

スクリーンショット 2022-12-02 16.48.36.png

永続化されてないモデルオブジェクトを追加する

画面

スクリーンショット 2022-12-02 16.49.26.png

書いたコード通りだと、追加ボタンを押すとJohn Doeさんが追加されます。

追加ボタンをクリックします。

スクリーンショット 2022-12-02 16.50.14.png

はい、追加されました。問題なさそうですね。ではもう一度クリックします。

スクリーンショット 2022-12-02 16.50.47.png

なにやら見慣れないエラーが出ましたね。

Queueing collections with multiple model connections is not supported.
複数のモデル接続を持つコレクションのキューイングはサポートされていません。

対処法

Modelオブジェクト生成時に接続先を教えてあげます。

Models/User.php
public function getConnectionName()
{
    return $this->connection ?? config('database.default');
}

なぜこんなエラーが起きるのか?

livewire内でEloquentCollectionを使うと、
レンダリングする度にEloquentCollection内のモデルオブジェクトを全て最新の状態にする処理が走ります。

実際に見てみましょう。

スクリーンショット 2022-12-02 16.59.31.png

まずこの状態から、DBを直接弄って一番上の人の名前を書き換えます

スクリーンショット 2022-12-02 17.00.18.png

この状態で追加ボタンを押してみます。

スクリーンショット 2022-12-02 17.00.43.png

はい、livewireコンポーネント内で再取得する処理を記述していないのに更新されました。

これを行おうとした際に発生するエラーという訳です。
実際にどういう処理が行われているのかはまた今度コードの海に潜ってみようと思います。

今回分かったのは大枠の原因と対処法です。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2