I am trying to write some code, that displays data from a database in Laravel. But I have two table values linked to eachother with a foreign key, and when I try to show that on my page, it just shows the id and not the actual name. I saw in another stackoverflow question that you should define the table data values in ur Model, but that doesn't work or I did it wrong. Can someone be so kind to help me fix this please? :)
Model Planet.php:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Planet extends Model
{
public function solar()
{
return $this->belongsTo(SolarSystems::class, 'id');
}
}
Model SolarSystems.php:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SolarSystems extends Model
{
public function planet()
{
return $this->belongsTo(Planet::class, 'solar_systems_id');
}
}
PlanetController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Planet;
use App\Models\SolarSystems;
class PlanetController extends Controller
{
public function index()
{
$planets = Planet::all();
$solar = SolarSystems::all();
return view('welcome', ['planets'=>$planets]);
}
public function show($planeet)
{
$planets = Planet::all();
$solar = SolarSystems::all();
$planets = collect($planets)->where('name', $planeet);
return view('welcome', ['planets' => $planets]);
}
}
welcome.blade.php:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Nunito', sans-serif;
}
</style>
</head>
<body>
@foreach ($planets as $planeten)
<ul>
<li>{{ ucfirst($planeten->name) }}</li>
<p>{{ ucfirst($planeten->description) }}</p>
<p>{{ ucfirst($planeten->solar_systems_id) }}
</ul>
@endforeach
</body>
</html>
import.sql:
CREATE DATABASE laravel;
USE laravel;
CREATE TABLE planets (
id int(11) AUTO_INCREMENT,
name text,
description text,
size_in_km int(11),
solar_systems_id int(11),
PRIMARY KEY (id)
);
CREATE TABLE solar_systems (
id int(11) AUTO_INCREMENT,
name text,
age_in_years int(11),
PRIMARY KEY (id)
);
INSERT INTO planets (name, description, size_in_km, solar_systems_id)
VALUES ('mars', 'Mars is the fourth planet from the Sun and the second-smallest planet in the Solar System, being larger than only Mercury.', 3389, 1);
INSERT INTO planets (name, description, size_in_km, solar_systems_id)
VALUES ('venus', 'Venus is the second planet from the Sun. It is named after the Roman goddess of love and beauty.', 6051, 1);
INSERT INTO planets (name, description, size_in_km, solar_systems_id)
VALUES ('earth', 'Our home planet is the third planet from the Sun, and the only place we know of so far thats inhabited by living things.', 6371, 1);
INSERT INTO solar_systems (name, age_in_years)
VALUES ('The Milky Way', 1360000000);
This is what I get right now, but instead of the '1' it needs to say: 'The Milky Way'
There few issues with your code;
You have 1-N relationship, a Planet belongsTo a Solar System and a Solar System hasMany Planet.
Planet.php
public function solar()
{
return $this->belongsTo(SolarSystems::class, 'solar_systems_id');
}
SolarSystems.php
public function planets()
{
return $this->hasMany(Planet::class, 'solar_systems_id');
}
PlanetController.php
public function show($planeet)
{
$planets = Planet
::with('solar')
->where('name', $planeet)
->get();
return view('welcome', ['planets' => $planets]);
}
Has you can see, I'm using with
and where
to optimize the query.
with
will eager load the relationship: well explained in the documentationwhere
will add a criteria to the database query, which will perform more efficiently than a collection. UsageSince you have loaded the relationship with the eager loading, you can directly have access to the model from the planet.
<p>{{ ucfirst($planeten->solar->name) }}