phplaravelforeachlaravel-bladelaravel-models

Laravel - Show name instead of id


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' enter image description here


Solution

  • There few issues with your code;

    Relationship

    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');
    }
    

    Controller

    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.

    View

    Since 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) }}