I have a polymorphic relationship between an Article
model and 3 models (Company
, Group
& User
) that sometimes returns null
.
90% of the time, the articleable relation is perfectly OK and looks like this:
#relations: array:1 [▼
"articleable" => AppModelsUser {#1443 ▼
#connection: "mysql"
#table: "users"
#primaryKey: "id"
#keyType: "int"
+incrementing: false
#with: array:2 [▶]
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#escapeWhenCastingToString: false
#attributes: array:7 [▶]
#original: array:7 [▶]
#changes: []
#casts: []
#classCastCache: []
#attributeCastCache: []
#dates: array:1 [▶]
#dateFormat: null
#appends: array:1 [▶]
#dispatchesEvents: []
#observables: []
#relations: array:2 [▶]
#touches: []
+timestamps: true
#hidden: array:2 [▶]
#visible: []
#fillable: []
#guarded: array:1 [▶]
#rememberTokenName: "remember_token"
}
]
But sometimes (1 / 10 ~), the relation is null
:
#relations: array:1 [▼
"articleable" => null
]
However, my model’s attribute seems perfectly fine:
#attributes: array:8 [▼
"id" => "e5db380f-9516-491f-bf5d-c13eb2978eac"
"articleable_type" => "AppModelsUser" ←
"articleable_id" => "20e00040-477b-44c5-800f-629a2380afe3" ←
"title" => "Between yourself and me.' 'That's the most."
"content" => "Alice. 'And ever since that,' the Hatter went on, spreading out the verses the White Rabbit interrupted: 'UNimportant, your Majesty means, of course,' the Mock ▶"
"image_url" => "https://via.placeholder.com/640x480.png/005511?text=non"
"created_at" => "2022-07-27 11:51:01"
"updated_at" => "2022-07-27 11:51:01"
]
And my DB does have the record (JSON export from my users
table):
[
{
"id": "20e00040-477b-44c5-800f-629a2380afe3",
"email": "[email protected]",
"email_verified_at": "2022-07-27 11:51:01",
"password": "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi",
"remember_token": "3gRso464ST",
"created_at": "2022-07-27 11:51:01",
"updated_at": "2022-07-27 11:51:01"
}
]
My models look like this:
User:
AppModelsUser ..........................................
Database ........................................... mysql
Table .............................................. users
Attributes ................................... type / cast
id unique ..................................... string(36)
email unique, fillable ....................... string(255)
email_verified_at nullable, fillable . datetime / datetime
password fillable, hidden .................... string(255)
remember_token nullable, fillable, hidden .... string(100)
created_at nullable, fillable ........ datetime / datetime
updated_at nullable, fillable ........ datetime / datetime
type appended .................................. attribute
Relations ................................................
profile HasOne .................... AppModelsUserProfile
companies BelongsToMany ............... AppModelsCompany
groups BelongsToMany .................... AppModelsGroup
page MorphOne ............................ AppModelsPage
articles MorphMany .................... AppModelsArticle
notifications MorphMany IlluminateNotificationsDatabaseNotification
Company:
AppModelsCompany .......................................
Database ........................................... mysql
Table .......................................... companies
Attributes ................................... type / cast
id unique ..................................... string(36)
name fillable ................................. string(60)
description nullable, fillable ............... text(65535)
created_at nullable, fillable ........ datetime / datetime
updated_at nullable, fillable ........ datetime / datetime
type appended .................................. attribute
Relations ................................................
page MorphOne ............................ AppModelsPage
articles MorphMany .................... AppModelsArticle
Group:
AppModelsGroup .........................................
Database ........................................... mysql
Table ............................................. groups
Attributes ................................... type / cast
id unique ..................................... string(36)
name fillable ................................. string(60)
description nullable, fillable ............... text(65535)
created_at nullable, fillable ........ datetime / datetime
updated_at nullable, fillable ........ datetime / datetime
type appended .................................. attribute
Relations ................................................
page MorphOne ............................ AppModelsPage
articles MorphMany .................... AppModelsArticle
These models use the following HasArticles
Trait:
<?php
namespace AppModelsTraits;
use AppModelsArticle;
use IlluminateDatabaseEloquentRelationsMorphMany;
trait HasArticles
{
/**
* Return model's articles.
*
* @return MorphMany
*/
public function articles(): MorphMany
{
return $this->morphMany(Article::class, 'articleable');
}
}
Article
AppModelsArticle .......................................
Database ........................................... mysql
Table ........................................... articles
Attributes ................................... type / cast
id unique ..................................... string(36)
articleable_type fillable .................... string(255)
articleable_id fillable ....................... string(36)
title fillable ................................ string(70)
content fillable .................................... text
image_url nullable, fillable ................. string(255)
created_at nullable, fillable ........ datetime / datetime
updated_at nullable, fillable ........ datetime / datetime
Relations ................................................
The Article
model has the following MorphTo
relationship:
public function articleable(): MorphTo
{
return $this->morphTo(__FUNCTION__, 'articleable_type', 'articleable_id');
}
My create_articles_table
migration (up Schema):
Schema::create('articles', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->uuidMorphs('articleable');
$table->string('title', '70');
$table->longText('content');
$table->string('image_url')->nullable();
$table->timestamps();
});
I am debugging in a Controller using the following:
$articles = Article::query()
->with('articleable')
->inRandomOrder()
->first();
dd($articles, $articles->articleable?->toArray());
Am I missing something? Thanks for your help.
Env:
PHP: 8.1
Laravel: 9.22
Nginx
MariaDB 10.7.4
2
Answers
Turns out the solution was to not use
Str::uuid()
(which usesRamseyUuidUuid::uuid4()
) to create my models' UUID, but to useRamseyUuidUuid::uuid6()
instead. No more issues, everything works fine now.The problem is that you need to separate the first() method from the with(‘articleable’), i have chek up and it looks like modify the query in some way. Instead of with() use the load after that you have the result.