framework: Unexpected behavior in firstOrNew method in belongs to many relationships
- Laravel Version: v9.17.0
- PHP Version: 8.1.7
- Database Driver & Version: MySQL 8.0.29
Description:
There is an unexpected behavior in firstOrNew method in belongsToMany relationships. When I try to firstOrNew a related model which it doesn’t exist, I get the first record of database which I shouldn’t.
Steps To Reproduce:
I have a ContentPost model which has a belongsToMany relationship with UploaderFile and the pivot table is called uploader_attachments.
This is the relation method in ContentPost:
public funciton files()
{
return $this->belongsToMany(UploaderFile::class, "uploader_attachments", "model_id", "file_id")
->withPivot("group", "model_name")
->withTimestamps()
->where("model_name", "ContentPost")
;
}
When I try to find a UploaderFile with a original_name which doesn’t exist, It returns a new empty instance as below:
# executed query on uploader-file model:
(new UploaderFile)->where("original_name","something not exists")->firstOrNew();
# results:
App\Models\UploaderFile {
id: 0,
}
But when I execute this query on the ContentPost’s files relation method. It gives me the first record.
# executed query on content-post files relation method:
(new ContentPost)->files()->where("original_name","something not exists")->firstOrNew();
# results:
App\Models\UploaderFile {
id: 1,
original_name: "24432660_0.jpg",
extension: "jpg",
mime_type: "image/jpeg",
given_name: "1578837071_SW4zL94LHGn1ZYb5VrHHkFljJ8PCHjH6BCYfMGAx",
private: 0,
created_at: "2020-01-12 17:21:11",
updated_at: "2020-01-12 17:21:11",
deleted_at: null,
created_by: 2,
updated_by: 0,
deleted_by: 0,
meta: "{"versions":["panel_thumb"]}",
}
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 16 (11 by maintainers)
There is a real unexpected behavior when even a model has been attached to the specified model. As you see in this image, my model (ContentPost) already has a file. It has been attached to an UploaderFIle with ID of 207, but in
firstOrNewmethod it still gets the first record of UploaderFiles!!We always expect the first and firstOrNew methods to behave the same when a model exists, but they have different behaviors.
Hi @driesvints, thanks for your answering. I think you misunderstood the problem. You know, it is not even about a where clause. Normal
belongsToManyrelationship can cause this problem.Please check this image which is taken from the tinker:
This happens because no ContentPosts are loaded, so it will grab the first record. it is the same as when you fetch it directly from UploaderFile: image
The problem is when you already loaded a content-post model and you know it doesn’t have any files. But in
firstOrNewmethod, it is loading the first record still: imageIn Laravel8, the same code was returning an empty instance of the
UploaderFile, which it was correct.