1
votes

I'm a beginner in Laravel, I need to show a name instead of an ID in Laravel blade.

These are the tables in the database:

city:

+----+--------+
| id | name   |
+----+--------+
|  1 | Vienna |
|  2 | Linz   |
+----+--------+

zip:

+----+---------+------+-------------+
| id | city_id | code | name        |
+----+---------+------+-------------+
|  1 |       1 | 1010 | 1. district |
|  2 |       1 | 1020 | 2. district |
|  3 |       1 | 1030 | 3. district |
|  4 |       2 | 4020 | Linz        |
+----+---------+------+-------------+

street:

+----+--------+---------------+
| id | zip_id | name          |
+----+--------+---------------+
|  1 |      1 | Burgring      |
|  2 |      1 | Seilergasse   |
|  3 |      2 | Praterstrasse |
+----+--------+---------------+

orders:

+----+---------+------+-----+--------+
| id | orderno | city | zip | street |
+----+---------+------+-----+--------+
|  1 | 100001  | 1    | 2   | 3      |
|  2 | 100002  | 1    | 1   | 2      |
|  3 | 100003  | 1    | 1   | 1      |
+----+---------+------+-----+--------+

Controller:

$orders = Order::all();
return view('orders-show', compact('orders'));

Blade:

@foreach($orders as $order)
    <tr>
        <td>{{$order->id}}</td>
        <td>{{$order->orderno}}</td>
        <td>{{$order->city}}</td>
        <td>{{$order->zip}}</td>
        <td>{{$order->street}}</td>
    </tr>
@endforeach

Result: Result

The result I expect: expected result

I believe there is a much better way than to create a view function for each item. As I read it, I suppose that through Model, can connect city, zip and street, something like belongsTo and hasMany.

Can anyone help me?

1

1 Answers

0
votes

You can do it using One To Many relationship.

First of all, update your orders table to use Eloquent Relationships properly:

+----+---------+---------+--------+-----------+
| id | orderno | city_id | zip_id | street_id |
+----+---------+---------+--------+-----------+
|  1 | 100001  | 1       | 2      | 3         |
|  2 | 100002  | 1       | 1      | 2         |
|  3 | 100003  | 1       | 1      | 1         |
+----+---------+---------+--------+-----------+

1. Define a relationship between city and zip tables:

Add this to your zip table migration:

$table->foreign('city_id')->references('id')->on('city')->onDelete('cascade');

Then, define city() method in your Zip model class:

public function city()
{
    return $this->belongsTo('App\City');
}

2. Define a relationship between zip and street tables:

Add this to your street table migration:

$table->foreign('zip_id')->references('id')->on('zip')->onDelete('cascade');

Then, define zip() method in your Street model class:

public function zip()
{
    return $this->belongsTo('App\Zip');
}

3. Define a relationship between city, zip, street and orders tables:

Add these lines to your orders table migration:

$table->foreign('city_id')->references('id')->on('city');
$table->foreign('zip_id')->references('id')->on('zip');
$table->foreign('street_id')->references('id')->on('street');

Then, define a method for each of these relationships in your Order model class:

public function city()
{
    return $this->belongsTo('App\City');
}

public function zip()
{
    return $this->belongsTo('App\Zip');
}

public function street()
{
    return $this->belongsTo('App\Street');
}

4. Now use them in your view (blade):

@foreach($orders as $order)
    <tr>
        <td>{{ $order->id }}</td>
        <td>{{ $order->orderno }}</td>
        <td>{{ $order->city['name'] }}</td>
        <td>{{ $order->zip['code'] }}</td>
        <td>{{ $order->street['name'] }}</td>
    </tr>
@endforeach

Note: Table names are plural by default in Laravel Eloquent. If you want to keep your table names singular, do not forget to set the $table property inside of your models. For example, in your City model class:

protected $table = 'city';