Model (with relationship) databiding... Bug?

Hello all,
I’m fairly new to Livewire, so I’m not sure if it’s a bug or something that I’ve missed but I’m experiencing a rather weird behaviour with a wire:model databinding to a model propertie:

I’m editing a Comment (with a text property) which belongsTo a Post. In the component I have a public Comment $comment; and in my Blade template (in an Edit modal , actually) I have an <input wire:model="comment.text">.

Everything works fine at first: a dd($this->comment); shows 5 attributes ["id", "text", "post_id", "created_at", "updated_at"]

But as soon as I’ve modified the text and I’m trying to save that, the same dd($this->comment); now shows 6 attributes ["id", "text", "post_id", "created_at", "updated_at", "post"]. The last post attribute being an array (with all the attributes of the corresponding Post).

And when calling $this->comment->save() the app breaks on an:

Illuminate\Database\QueryException
SQLSTATE[HY000]: General error:1 no such column: post

It seems to me that wire:model messed something there, creating an attribute that shouldn’t be there (and if we were to access $comment->post, we should get a Post model and not an array anyway).

I’ve upgraded to the last version of Laravel and Livewire.

Any idea on the what or why ? Thanks in advance.

must be wire:model="comment.text", and you have to define rules() methods for the property

protected $rules = [
   'comment.text' => 'required'
];
1 Like

That was a typo on my part (that I’ve corrected, thanks!), I have, indeed wire:model="comment.text in the Blade template.

And even if I forgot to mention it, the $rules are also defined exactly as you wrote them (if not the wouldn’t be properly filled).

Unfortunately, it’s not what’s problematic in this case…

Does your Comment model eager load the Post relationship?

There is no eager loading, just a regular type hinted dependancy injection:

public function edit(Comment $comment)
{
    $this->comment = $comment;
}

but the following code produces the same result:

public function edit($commentId)
{
    $this->comment = Comment::findOrFail($commentId);
}

But, as I mentioned in my OP, if you dd($this->comment) in this method, the result is correct. The problem occurs in the save() method (after editing the value):

public function save()
{
    // dd($this->comment);    <- Shows an extra *post* attribute of type **Array**
    $this->comment->save();    // <- Throws the QueryEXception
}

Try this to see if the Post disappears:
dd($this->comment->withoutRelations())

Calling the withoutRelations method doesn’t change anything, the post attribute is still there…

I’ve tried and debug inside of Livewire and I’ve noticed that in the hydrate method (of the PerformDataBindingUpdates class), the $unHydratedInstance (which is the actual Comment) already has that attribute… So it seems that the problem occurs before the Hydrate lifecycle, but I’ve not been able to find where/when, yet.

What is the edit function doing?
If you have public Comment $comment and <input wire:model="comment.text"> then all you need is $this->comment->save()

The edit method is only responsible for setting the public Comment $comment on the component (with the one selected from all displayed comments).

What you wrote is exactly how I thought it should work and yet, it doesn’t seem to… So I’m guessing there’s a bug hidden, and I’m going to open an issue with a repo to reproduce it… Thanks for your time, @Pom

Can you post your view code?