Reputation: 130
Before I start: I already read the "Similar questions" suggestions, and although there are indeed many similar questions with problem like mine, I haven't find the solutions yet. I also only started to learn Laravel for a few days, so please bear with me.
I'm using the latest Laravel framework (7.18.0). I have three tables:
pirates
----------
pirate_id serial NOT NULL, -- PK
pirate_name character varying(200) NOT NULL,
beard_size integer NOT NULL,
beard_color integer NOT NULL,
beard_sizes
----------
beard_size_id serial NOT NULL, -- PK
beard_size character varying(100) NOT NULL
beard_colors
----------
beard_color_id serial NOT NULL, -- PK
beard_color character varying(100) NOT NULL
I generated the model with php artisan command and tried to define the models:
Pirate.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Pirate extends Model
{
public $timestamps = false;
protected $primaryKey = 'pirate_id';
protected $fillable = ['pirate_name', 'beard_size', 'beard_color'];
public function beardSize()
{
return $this->belongsTo('App\BeardSize', 'beard_size_id');
}
public function beardColor()
{
return $this->belongsTo('App\BeardColor', 'beard_color_id');
}
}
BeardSize.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class BeardSize extends Model
{
public $timestamps = false;
protected $primaryKey = 'beard_size_id';
protected $fillable = ['beard_size'];
public function pirates()
{
return $this->hasMany('App\Pirate', 'pirate_id');
}
}
BeardColor.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class BeardColor extends Model
{
public $timestamps = false;
protected $primaryKey = 'beard_color_id';
protected $fillable = ['beard_color'];
public function pirates()
{
return $this->hasMany('App\Pirate', 'pirate_id');
}
}
Tried to display my "pirates" table's data, this is my controller:
PirateController.php
<?php
namespace App\Http\Controllers;
use App\Pirate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class PirateController extends Controller
{
public function main()
{
$pirates = Pirate::paginate(4);
return view('main', ['pirates' => $pirates]);
}
}
and here is my view:
main.blade.php
@extends('pirate')
@section('main_nav', 'This is our ship')
@section('main_content')
<p>List of our crew:</p>
<table class="table-view">
<thead>
<tr>
<th style="width: 60px;">No.</th>
<th>Name</th>
<th style="width: 160px;">Beard size</th>
<th style="width: 160px;">Beard color</th>
<th> </th>
<th> </th>
</tr>
</thead>
<tbody>
@foreach($pirates as $ind => $pirate)
<tr>
<td>{{ ($ind + 1) . '.' }}</td>
<td>{{ $pirate->pirate_name }}</td>
<td>{{ $pirate->beardSize->beard_size }}</td>
<td>{{ $pirate->beardColor->beard_color }}</td>
<td class="table-nav"><a href="update/{{$pirate->pirate_id}}">edit</a></td>
<td class="table-nav"><a href="delete/{{$pirate->pirate_id}}">delete</a></td>
</tr>
@endforeach
</tbody>
</table>
{{ $pirates->links() }}
@endsection
Every time I tried to get the relation table's data (beard_sizes
and beard_colors
), I got errors either: Trying to get property 'beard_size' of non-object
or Trying to get property 'beard_color' of non-object
. For the record, the beard_size
and beard_color
column in pirates
table are not null.
Regarding the field names in the database tables, the documentation mentioned how primary key should be written with id
, etc., however in my next project, I'm using an already existing database with 100+ tables, so changing the name of the columns is impossible.
Upvotes: 1
Views: 1568
Reputation: 76699
NOT NULL
probably does not suffice for a primary key; set it to UNSIGNED
, BIGINT
and enable AUTOINCREMENT
. The name of the column does not really matter. I mean, usually one can simply define it's name: protected $primaryKey = 'pirate_id';
...as you already have it.
And the one-to-many relationship of App\Pirate
should be represented as:
Well, actually it's one-to-one ...as 1 pirate only has 1 beard.
public function beardSize()
{
return $this->hasOne('App\BeardSize', 'beard_size_id');
}
public function beardColor()
{
return $this->hasOne('App\BeardColor', 'beard_color_id');
}
Upvotes: 1
Reputation: 3764
With your schema you have provided you need to have the following relationships:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Pirate extends Model
{
public $timestamps = false;
protected $primaryKey = 'pirate_id';
protected $fillable = ['pirate_name', 'beard_size', 'beard_color'];
public function beardSize()
{
return $this->belongsTo('App\BeardSize', 'beard_size', 'beard_size_id');
}
public function beardColor()
{
return $this->belongsTo('App\BeardColor', 'beard_color', 'beard_color_id');
}
}
A belongsTo relationship has the following structure:
return $this->belongsTo(Related::class, 'key_on_own_table', 'key_on_related_table');
Upvotes: 2