belongsTo throwing Trying to get property 'jenis_bahan' of non-object - php

Model of BahanLab
protected $table = 'bahan_labs';
protected $primaryKey = 'kode_bahan';
protected $fillable = ['kode_bahan', 'nama_bahan', 'kode_sinta', 'kode_jenis', 'harga_bahan', 'stok', 'satuan', 'minimum_stok'];
public $timestamps = false;
public function jenis()
{
return $this->belongsTo('App\JenisBahan', 'kode_jenis');
}
Model of JenisBahan
protected $table = 'jenis_bahans';
protected $primaryKey = 'kode_jenis_bahan';
protected $fillable = ['kode_jenis_bahan', 'jenis_bahan'];
public $timestamps = false;
public function bahans()
{
return $this->hasMany('App\BahanLab');
}
I'm pretty sure that this is correct, I already define the relationship between these tables. But when I tried to do looping echo $bahan->jenis->jenis_bahan, it throws exception.
I already tried some suggestion to do dd($bahan->jenis->jenis_bahan) and I got null, so what is really happening?
UPDATE
Controller:
$bahans = BahanLab::with('jenis')->get();
return view('bahan.daftar-bahan', compact('bahans'));
View:
<tbody>
#foreach($bahans as $bahan)
<tr>
<td>{{ $bahan['kode_bahan'] }}</td>
<td>{{ $bahan['nama_bahan'] }}</td>
<td>{{ $bahan->jenis->jenis_bahan }}</td>
<td>{{ $bahan['harga_bahan'] }}</td>
<td>{{ $bahan['stok'] }} {{ $bahan['satuan'] }}</td>
</tr>
#endforeach

Since you're looping, one of your $bahan objects doesn't have a jenis object (meaning $bahan->jenis is null, so you can't access jenis_bahan of a non-object, of which null is). To handle this, prevent loading $bahans unless it has a jenis, or check for it in the loop:
Controller:
$bahans = BahanLab::has('jenis')->with('jenis')->get();
return view('bahan.daftar-bahan', compact('bahans'));
Or, in your view:
<tbody>
#foreach($bahans as $bahan)
<tr>
<td>{{ $bahan['kode_bahan'] }}</td>
<td>{{ $bahan['nama_bahan'] }}</td>
#if($bahan->jenis)
<td>{{ $bahan->jenis->jenis_bahan }}</td>
#else
<td>No Jenis...</td>
#endif
<td>{{ $bahan['harga_bahan'] }}</td>
<td>{{ $bahan['stok'] }} {{ $bahan['satuan'] }}</td>
</tr>
#endforeach
Note: This #if() check is unnecessary if using ->has('jenis').
Also, you can use ->with() and ->has() together; ->has() restricts the query results to those that have a jenis relationship, ->with() eager loads it to increase performance in large datasets.

It's occured because my table I is a string, not an incremental Integer.
So to solve this problem, I just had to set
public $incrementing = false;

Related

Attempt to read property "match_name" on null laravel-8

I have
ErrorException
Attempt to read property "match_name" on null (View: C:\xampp\htdocs\Cbangla\resources\views\admin\manage\score\index.blade.php)
Error
I want to fetch all data from my score tables This is my scores table database view
To fetch, all data from the scores table This is what I have in my ScoreController.php
public function index()
{
$data=Score::all();
$team=Team::all();
$match=Matchh::all();
$player=Player::all();
return view('admin.manage.score.index',compact('data','team','match','player'));
}
This is my Score.php model
protected $fillable = ['score_name','score_slug','team_id','match_id','player_id'];
public function team(){
return $this->belongsTo(Team::class);
}
public function matchh(){
return $this->belongsTo(Matchh::class);
}
public function playre(){
return $this->belongsTo(Player::class);
}
This is my index.blade.php
#foreach ($data as $key => $row)
<tr>
<td>{{ $key + 1 }}</td>
<td>{{ $row->score_name }}</td>
<td>{{ $row->score_slug }}</td>
<td>{{ $row->matchh->match_name }}</td>
<td>{{ $row->team->team_name }}</td>
<td>{{ $row->player->player_name }}</td>
</tr>
#endforeach
As I see, there is problem when score has not match or match not found.
First of all, you have to specify relation column, because your model is named Matchh and laravel is looking for matchh_id column.
Solution:
# Score.php model
public function matchh(){
return $this->belongsTo(Matchh::class,'match_id');
}
Tip 1:
You can use optional function, when you're not sure if model has relation or not
#foreach ($data as $key => $row)
<tr>
<td>{{ $key + 1 }}</td>
<td>{{ $row->score_name }}</td>
<td>{{ $row->score_slug }}</td>
<td>{{ optional($row->matchh)->match_name }}</td>
<td>{{ optional($row->team)->team_name }}</td>
<td>{{ optional($row->player)->player_name }}</td>
</tr>
#endforeach
Tip 2:
You can use whereHas function to be sure that Score has Matchh
public function index()
{
$data=Score::query()->whereHas('matchh')->get();
$team=Team::all();
$match=Matchh::all();
$player=Player::all();
return view('admin.manage.score.index',compact('data','team','match','player'));
}
Please add match_id to matchh relationship case the name of your relationship is different than the match id you stored in database
public function matchh(){
return $this->belongsTo(Matchh::class,'match_id');
}
You must provide key in relation because your method name is matchh and in that case relation except matchh_id but in you case it must be match_id.
So:
public function matchh(): BelongsTo
{
return $this->belongsTo(Matchh::class, 'match_id');
}

Undefined property: stdClass::$salarie

I have two table SALARIES and POINTAGES And between them a relationship hasMany belongsTo, I want to display for each POINTAGE a SALARIES corresponds but it gives me this error:
Undefined property: stdClass::$salarie
consulter.blade.php
#foreach($pointages as $pointage)
<tr>
<td>{{ $pointage->datep }}</td>
<td>{{ $pointage->chantier }}</td>
<td>{{ $pointage->ouvrage }}</td>
<td>{{ $pointage->nbrj }}</td>
<td>{{ $pointage->solde }}</td>
<td>{{ $pointage->salarie->nom }}</td>
</tr>
#endforeach
Pointage.php
protected $fillable = [
'salarie_id', 'datep', 'solde', 'nbrj' , 'ouvrage' , 'chantier' , 'prime' ,
];
public function salarie(){
return $this->belongsTo('App\Salarie');
}
Salarie.php
public function pointages(){
return $this->hasMany('App\Pointage');
}
pointages migration:
public function up(){
Schema::table('pointages', function (Blueprint $table) {
$table->integer('salarie_id')->unsigned()->after('id');
$table->foreign('salarie_id')->references('id')->on('salaries');
});
}
SalarieController.php
public function consulter(){
$salaries = Salarie::with('pointages')->get();
$pointages = DB::table('pointages')->get();
return view('salarie.consulter', compact('salaries','pointages'));
}
If you want to use a relationship, like public function salarie() on your Pointage model, you need to actually query it. Don't use DB::table(), use Pointage:
$pointages = Pointages::get();
Also, to avoid additional queries when looping $pointages, eager load your relationship:
$pointages = Pointages::with(["salarie"])->get();
In summary, DB::table() does not return a Pointage model, so you can't use ->salarie. Use your model.
Edit: There is a chance that a Pointage doesn't have a Salarie associated, so you need to handle that. Either enforce the relationship with a ->has() query, or check while looping:
$pointages = Pointages::with(["salarie"])->has("salarie")->get();
Or, in your view:
#if($pointages->salarie)
<td>{{ $pointage->salarie->nom }}</td>
#else
<td>No Salarie...</td>
#endif

Laravel Eloquent Relationship Confusion

Here is my situation;
I have an agreements table which will list the different types of agreements there are. It's a lookup table basically.
I have a client_agreements table which list which clients have signed up to which type of agreement. I have an agreement_id within this table (foreign key id).
As I am using Laravel, here is my Controller method to view all agreements for a specific client;
public function index($client_id)
{
$client_agreements = Agreement::find($client_id);
return View::make('client_agreements.index')
->with('client_agreements', $client_agreements);
}
Here is my Agreement Model;
class Agreement extends Eloquent {
protected $table = 'agreements';
public function client_agreements(){
return $this->hasMany('ClientAgreement', 'agreement_id');
}
}
So I want to output in the view from the agreements table;
agreement_type
level
and from the client_agreements table;
start_date
expire_date
My View code (which I'm sure is wrong but don't know why) is essentially;
#foreach($client_agreements as $client_agreement)
<tr>
<td>{{ $client_agreement->agreement_type }}</td>
<td>{{ $client_agreement->level }}</td>
<td>{{ $client_agreement->start_date }}</td>
<td>{{ $client_agreement->expire_date }}</td>
</tr>
#endforeach
What am I doing wrong?
You can do it like this:
$client = Client::with('agreements')->find($client_id);
$client_agreements = $client->agreements;
return View::make('client_agreements.index')
->with('client_agreements', $client_agreements);
And in your view:
#foreach($client_agreements as $client_agreement)
<tr>
<td>{{ $client_agreement->agreement_type }}</td>
<td>{{ $client_agreement->level }}</td>
<td>{{ $client_agreement->pivot->start_date }}</td>
<td>{{ $client_agreement->pivot->expire_date }}</td>
</tr>
#endforeach
This would require the following setup:
Client model
class Client extends Eloquent {
public function agreements(){
return $this->belongsToMany('Agreement', 'client_agreements')->withPivot('id', 'start_date', 'expire_date');
}
}
Agreement model
class Agreement extends Eloquent {
public function clients(){
return $this->belongsToMany('Client', 'client_agreements')->withPivot('id', 'start_date', 'expire_date');
}
}
For more information read the Eloquent docs (especially the section about relationships)

Laravel hasMany relationship not looping through to display results

An alert can have many messages associated with it, through a foreign key. Each message sent is also attached to a user, through a foreign key. On viewing the alert, if such messages exist (they are not required), I want to display each message, along with the associated user's details.
User model:
public function alerts()
{
return $this->hasMany('Alert');
}
public function messages()
{
return $this->hasMany('Message');
}
Alert model:
public function user()
{
return $this->belongsTo('User');
}
public function messages()
{
return $this->hasMany('Message');
}
I have noticed if the alert doesn't have any messages associated with it, the forloop doesn't work!
Within my show view, I have:
#foreach($alerts as $alert)
<tr>
<td>{{ $alerts->messages->first()->firstname }}</td>
<td>{{ $alerts->messages->first()->user->email }}</td>
<td>{{ $alerts->messages->first()->user->phone_number }}</td>
<td>{{ $alerts->messages->first()->message }}</td>
<td>{{ date("j F Y", strtotime($alerts->messages->first()->created_at)) }}</td>
<td>{{ date("g:ia", strtotime($alerts->messages->first()->created_at)) }}</td>
</tr>
#endforeach
Which works great, if there are messages to show, but it only loops through the first message, not the rest of them. The controller pulling in the data is:
public function show($id)
{
$alert = Alert::where('id','=',$id)->first();
$this->layout->content = View::make('agents.alert.show',
array('alerts' => $alert));
}
Any guidance as to why the forloop doesn't work when there is less 2 results, and why it only loops through the first result. Thank you.
First I suggest using eager loading for related models or you will run many db queries that you don't want nor need:
public function show($id)
{
$alert = Alert::with('messages.user')->where('id','=',$id)->first();
$this->layout->content = View::make('agents.alert.show', array('alert' => $alert));
}
Then in you view spin through messages, not alerts as you don't have many of them:
#foreach($alert->messages as $message)
<tr>
<td>{{ $message->firstname }}</td>
// if you are sure there is a user for each message, otherwise you need a check for null on $message->user
<td>{{ $message->user->email }}</td>
<td>{{ $message->user->phone_number }}</td>
<td>{{ $message->message }}</td>
<td>{{ date("j F Y", strtotime($message->created_at)) }}</td>
<td>{{ date("g:ia", strtotime($message->created_at)) }}</td>
</tr>
#endforeach

Getting pivot and reltated tables column values Laravel 3

Good evening peeps, I'm playing a little bit with Laravel, and I have this situation. I have 2 models and 3 tables to display vital signs from a pacient.
Table pacient:
id
names
birthdate
Table vital_sign:
id
description
unit
table pacient_vital_sign
id
pacient_id
vital_sign_id
first_value
second_value
date_time_taken
And the 2 models:
class Pacient extends Eloquent{
public static $timestamps = false;
public function vital_signs(){
return $this->has_many_and_belongs_to('VitalSign', 'pacient_vital_sign', 'pacient_id', 'vital_sign_id');
}
}
class VitalSign extends Eloquent{
public static $timestamps = false;
public static $table = 'vital_signs';
public function pacients(){
return $this->has_many_and_belongs_to('Pacient', 'pacient_vital_sign', 'vital_sign_id', 'pacient_id');
}
}
And for my view I'm sending the pacient whose vital signs I want to display:
$pacient = Pacient::where('active', '=', 1)->first();
So, based on the documentation I could do this to show the pivotal table data:
#foreach($pacient->vital_signs as $sv)
<tr>
<td>{{ $sv->pivot->date_time_taken }}</td>
<td>{{ $sv->description }}</td>
<td>{{ $sv->pivot->first_value }} {{ $sv->pivot->second_value }}</td>
</tr>
#endforeach
But this way, neither the date_time_taken value nor first_value or second_value is showed. Description is displayed.
Now, if I do something like this
#foreach($pacient->vital_signs()->pivot()->get() as $sv)
<tr>
<td>{{ $sv->date_time_taken }}</td>
<td>{{ $sv->description }}</td>
<td>{{ $sv->first_value }} {{ $sv->second_value }}</td>
</tr>
#endforeach
date_time_taken, first_value and secon_value are displayed but I dont know how to reverse the relationship in order to display the value for the related table column, in this case, description from vital_sign table
So I both cases, I'm missing something. Any ideas? What I'm missings?
Thanks
On the Docs:
By default only certain fields from the pivot table will be returned
(the two id fields, and the timestamps). If your pivot table contains
additional columns, you can fetch them too by using the with() method
So in my case, on both models:
return $this->has_many_and_belongs_to('VitalSign', 'pacient_vital_sign', 'pacient_id', 'vital_sign_id')->with('col1', 'col2', 'coln');
and this will work:
#foreach($pacient->vital_signs as $sv)
<tr>
<td>{{ $sv->pivot->date_time_taken }}</td>
<td>{{ $sv->description }}</td>
<td>{{ $sv->pivot->first_value }} {{ $sv->pivot->second_value }}</td>
</tr>
#endforeach
I found this to be useful, but a quick addendum for Laravel 4:
return $this->belongsToMany('Model','pivot_table','this_id','foreign_id')->withPivot('col1','col2');

Categories