I'm having an issue with a hasMany
-relation in my Laravel application.
I'm sure, it is a simple question, but currently I'm struggling with it and can't find the reason.
I have a Model called LandingPage
:
<?php
namespace app\Models\LandingPage;
class LandingPage extends \App\Models\Base
{
public $table = "landing_pages";
protected $fillable = [
'name',
'event_id',
'url_id',
'is_update_needed',
'view',
'created_at',
'updated_at',
];
protected $hidden = [
];
protected $appends = [
'app_icon',
'landing_page_url_base_path'
];
...
public function app_info() {
return $this->hasOne(\App\Models\App\AppInfo::class, "landing_page_id", "id");
}
public function app_images() {
return $this->hasMany(\App\Models\App\AppImage::class, "landing_page_id", "id");
}
public function app_texts() {
return $this->hasMany(\App\Models\App\AppText::class, "landing_page_id", "id");
}
...
}
The problem is on app_texts()
. I doesn't load the app_texts of my landing page.
As you can see there are similar relations app_info
& app_images
. I've copy/pasted the relation from app_images
to app_texts
. app_images
is working fine.
Here is the Model of AppText
:
<?php
namespace app\Models\App;
class AppText extends \App\Models\Base
{
public $table = "app_texts";
protected $fillable = [
'text',
'type',
'landing_page_id',
'created_at',
'updated_at'
];
protected $hidden = [
];
public function landing_page() {
return $this->hasOne(\App\Models\LandingPage\LandingPage::class, "id", "landing_page_id");
}
}
In the database is everything correctly set up:
I also can see in the Laravel Debugbar, that the query is not being executed to load the app_texts:
Have I forgotten something, or have I got something wrong?
The landing page is part of another Model (guests
). I call there the property landing_page
, but without calling the relations explicitly. It works for app_images
or app_info
, so I don't think, I need to call app_texts
explicitly.
This is the controller section where it is called:
public function showEvent(\Illuminate\Http\Request $request, string $eventName, string $guestIdentifierToken) {
$guest = $this->guestRepository->getByIdentifierToken($guestIdentifierToken);
if($guest != null) {
if($guest->landing_page->is_update_needed == 1) {
//...
//do some stuff
}
return view('event.landingpage', [
'eventUrl' => url()->current(),
'guest' => $guest,
'event' => $guest->event,
'landingPage' => $guest->landing_page
]);
}
else {
return redirect('/notFound');
}
}
It works, if I call the property explicitly:
$guest->landing_page->app_texts = $guest->landing_page->app_texts;
But why do I need to this for app_texts
and not for app_images
or app_info
?
Your LandingPage
model has two appends
on it:
protected $appends = [
'app_icon',
'landing_page_url_base_path'
];
When your LandingPage
model is converted to json, these two fields will be included, meaning that their associated accessors will be called. My guess is that you are using your app_info
and app_images
relationships inside your getAppIconAttribute()
and getLandingPageUrlBasePathAttribute()
accessor functions.
Since the relationships are used in those accessors, they will be included in the json output. However, since the app_texts
relationship is never used, it will not be included.
If you want your app_texts
relationship included in your json output, you will need to load it before you convert to json. The quickest solution for you is to just load it in your inside your showEvent()
function:
$guest->landing_page->load('app_texts');