3

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

Mauro
  • 342
  • 3
  • 10
  • Where is the relational table of the two tables ? Have you defined one that connects the two tables "planets" and "solar_systems"? Bear in mind that you need a specific key that is on both tables like the id of the solar_system for example. If you haven't set that, I think that you should first check how to set up a relational table and then set up your Model. – Oris Sin Jan 26 '22 at 11:40

3 Answers3

1

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) }}
Clément Baconnier
  • 5,718
  • 5
  • 29
  • 55
0

replace this line

<p>{{ ucfirst($planeten->solar_systems_id) }} 

with this line

<p>{{ ucfirst($planeten->solar()->name) }}</p> 
  • This cause a N+1 issue that could easily be solved with [eager loading](https://laravel.com/docs/8.x/eloquent-relationships#eager-loading) – Clément Baconnier Jan 26 '22 at 12:50
  • All I'm getting now is this error: 'Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name (View: C:\Users\mauro\OneDrive\Bureaublad\School\Bit Academy\18 Laravel\project\resources\views\welcome.blade.php)' – Mauro Jan 26 '22 at 12:55
  • So use `Planet::with('solar')->get()` instead of `Planet::all()` , and there is no need for the brackets just `

    {{ ucfirst($planeten->solar->name) }}

    `
    – Yazan Fouad Aldbaisy Jan 26 '22 at 12:55
0

Just replace this line

{{ ucfirst($planeten->solar_systems_id) }} 

with this line 

{{ ucfirst($planeten->solar->name) }}

Because you need to get the name from the relationship

Wael Khalifa
  • 895
  • 7
  • 17
  • 1
    Like the other answer, this cause a N+1 issue that could easily be solved with [eager loading](https://laravel.com/docs/8.x/eloquent-relationships#eager-loading) `$planets = Planet::with('solar')->get();` – Clément Baconnier Jan 26 '22 at 12:53