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" => App\Models\User {#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" => "App\Models\User" ←
"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:
App\Models\User ..........................................
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 .................... App\Models\UserProfile
companies BelongsToMany ............... App\Models\Company
groups BelongsToMany .................... App\Models\Group
page MorphOne ............................ App\Models\Page
articles MorphMany .................... App\Models\Article
notifications MorphMany Illuminate\Notifications\DatabaseNotification
Company:
App\Models\Company .......................................
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 ............................ App\Models\Page
articles MorphMany .................... App\Models\Article
Group:
App\Models\Group .........................................
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 ............................ App\Models\Page
articles MorphMany .................... App\Models\Article
These models use the following HasArticles
Trait:
<?php
namespace App\Models\Traits;
use App\Models\Article;
use Illuminate\Database\Eloquent\Relations\MorphMany;
trait HasArticles
{
/**
* Return model's articles.
*
* @return MorphMany
*/
public function articles(): MorphMany
{
return $this->morphMany(Article::class, 'articleable');
}
}
Article
App\Models\Article .......................................
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
CodePudding user response:
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.
$articles = Article::query()
->inRandomOrder()
->first();
$articles->load('articleable');// try to add a check if $articles return null
CodePudding user response:
Turns out the solution was to not use \Str::uuid()
(which uses Ramsey\Uuid\Uuid::uuid4()
) to create my models' UUID, but to use Ramsey\Uuid\Uuid::uuid6()
instead. No more issues, everything works fine now.