Trying to get property 'name' of non-object. Model relationship not working - laravel

I am getting an error message relating to my model relationship and have an identical section of my other app that works fine. I've looked through everything many times and cannot see any reason my model relationship should not work. When I try to access the model relationship in the view, I get "Trying to get property 'name' of non-object"
I have the following in my Controller:
public function edit($id)
{
//
$plansubmission = PlanSubmission::find($id);
$hradmins = PSPlanToHRAdminMapping::where('plan_submission_plan_id', $id)->get();
return view('planbuilder.add-hr-administrators', compact('plansubmission', 'hradmins'));
I have the following in my View:
<h3 class="py-3">Current HR Administrators with Online Access</h3>
<table class="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Email Address</th>
</tr>
</thead>
<tbody>
#foreach($hradmins as $hradmin)
<tr>
<td> {{$hradmin->hradmin->name }}</td>
<td> {{$hradmin->hradmin->email }}</td>
#endforeach
</tr>
</tbody>
</table>
I have the following in my Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class PSPlanToHRAdminMapping extends Model
{
//
protected $guarded = [];
public function hradmin()
{
return $this->belongsTo('App\HRAdmin');
}
}
I have the following Migration:
{
Schema::create('p_s_plan_to_h_r_admin_mappings', function (Blueprint $table) {
$table->unsignedBigInteger('plan_submission_plan_id');
$table->unsignedBigInteger('h_r_admin_id');
$table->timestamps();
$table->foreign('plan_submission_plan_id')->references('id')->on('plan_submissions');
$table->foreign('h_r_admin_id')->references('id')->on('h_r_admins');
});
}

It's possible that for some records you don't have any record for hradmin relationship so you can try adding optional helper like so:
<td> {{optional($hradmin->hradmin)->name }}</td>
<td> {{optional($hradmin->hradmin)->email }}</td>
for example to avoid error

Related

How do i count for a specific data in a column in Laravel?

I have two models, One is Employees and other one is Skill. One Employee can have many skills. Now I'm trying to show number of employees that possesses each consecutive skill in skills view page.
My Skills View Page:
<tbody>
#foreach ($skills as $skill)
<tr>
<th scope="row">{{ $loop->index+1 }}</th>
<td>{{ $skill->skill_name }}</td>
<td>{{ $skill->totalEmp($skill->id) }}</td>
<td style="width: 25%;">
<button class="btn btn-outline-danger" type="button" title="Delete Skill">Delete Skill</button>
</td>
</tr>
#endforeach
</tbody>
Skills Model:
class Skill extends Model
{
use HasFactory;
protected $fillable = [
'skill_name'
];
public function Employee()
{
return $this->hasMany(Employees::class, 'skill_id', 'id');
}
public function totalEmp($id){
return Employees::where('status', 1)->where('skill_id','=',$id)->count();
}
}
Employees Model:
class Employees extends Model
{
use HasFactory;
protected $guarded = [];
protected $table = 'employees';
public function Skills(){
return $this->hasMany(Skill::class);
}
}
Employee table has->skill_id, other irreverent fields || Skill Model has->id and skill_name field.
You can use withCount method for this.
https://laravel.com/docs/9.x/eloquent-relationships#counting-related-models
On your Skill model you have Employee relationship defined.
So you will be able to do something like this:
$skills = Skill::withCount(['Employee'])->get();
// Prints out number of employees that posses first skill
echo $skills[0]->employee_count;
Of course you can iterate through $skills with for loop, or foreach and similar, or even use collection methods.
<tbody>
#foreach ($skills as $skill)
<tr>
<th scope="row">{{ $loop->index+1 }}</th>
<td>{{ $skill->skill_name }}</td>
<td>{{ $skill->employee_count }}</td>
<td style="width: 25%;">
<button class="btn btn-outline-danger" type="button" title="Delete Skill">Delete Skill</button>
</td>
</tr>
#endforeach
</tbody>
If you still want to use your method totalEmp you can modify it like this:
public function totalEmp(){
return $this->employee()->count();
}
One other thing that I strongly recommend is to make sure you name your models and relationships properly.
Models should be named like: Skill and Employee
Relationships should be named like: employees() and skills()
Please see example here: https://laravel.com/docs/9.x/eloquent-relationships#many-to-many

How to count all the products that belongs to category(slug) Laravel 8

I am a beginner in Laravel. I need a little help.
I have an index.blade.php file which displays all the category names. When I click on on it will generate the slug link where I have all the products that in the category. So I would like to count only those products that is belongs to category's slug and display the number on the index.blade.php. Thanks for the help.
Route::get('view-category/{slug}', [ProductsController::class,'viewcategory']);
productsController:
public function viewcategory($slug){
if(Category::where('slug', $slug)->exists()){
$category = Category::where('slug', $slug)->first();
$products = Products::where('cateId', $category->id)->where('status','1')->get();
return view('admin.products.display', compact('category','products'));
}
else{
return redirect('/dashboard')->with('status',"Slug does not exist");
}
}
category Model:
class Category extends Model
{
use HasFactory;
protected $table = "categories";
protected $fullable = [
'name',
'slug',
'description',
'status',
'popular',
];
public function products(){
return $this->belongsTo(Products::class, 'id', 'cateId');
}
}
index.blade.php:
<thead>
<tr>
<th></th>
<th>Product Name</th>
<th>Category</th>
<th>Sub Category</th>
<th>Variations</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach($category as $item)
<tr>
<td class="control" tabindex="0"></td>
<td>{{$item->products->productName}}</td>
<td>{{$item->name}}</td>
<td>{{$item->subCategory}}</td>
<td>{{$item->counter}}</td>
<td></td>
<td></td>
</tr>
#endforeach
</tbody>
</table>
You can still call relationships inside your blade files, so if you have a products relationship setup correctly, you only need to change your index blade to this
<td>{{$item->products()->count()</td>
If you have categories that don't have any products put this in your blade to check before showing the count (Its an if else statement just inline)
<td>{{$item->products ? $item->products()->count() : 'N/A'}}</td>
in your blade file add this line before your foreach
#if( $category->posts->count() )
//your #foreach code here
#endif

How to return Model in Many to Many Polymorphic Associations in Laravel

I am able to successfully create the relationships, but I now want to identify what the model used in the relationship is, but I don't know how to access it. Could someone point me in the right direction? I have tried the following down below in the index.blade.php file, but it just returns NULL
1 Possible solution is to check to see if the value is empty on each relationship definition each time, but is there a laravel built in way to check?
#if ($event->services->isNotEmpty())
There are services!
#endif
Basically I have two relationships defined courses and services. I want to check which 1 each event is.
I have the following relationships:
services
courses
events
schedulables
event_user
Events.php model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Event extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
public function users()
{
return $this->belongsToMany('App\User');
}
public function courses()
{
return $this->morphedByMany('App\Course', 'schedulable');
}
public function services()
{
return $this->morphedByMany('App\Service', 'schedulable');
}
}
index.blade.php
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Start</th>
<th scope="col">End</th>
<th scope="col">Assigned</th>
<th scope="col">Type</th>
<th scope="col">Options</th>
</tr>
</thead>
<tbody>
#foreach ($events as $event)
<tr>
<th scope="row">{{$event->start_date}}</th>
<td>{{$event->end_date}}</td>
<td>{{$event->user->name}}</td>
<td>{{Illuminate\Database\Eloquent\Relations\Relation::getMorphedModel($event->getMorphClass())}}
</td>
<td>
<form action="{{route('events.destroy', $event)}}" method="POST">
#csrf
#method('DELETE')
<button type="submit" class="btn btn-outline-danger">Delete</button>
</form>
</td>
</tr>
#endforeach
</tbody>
</table>
According to the documentation, this piece of code only apply to a $service or $course model:
Illuminate\Database\Eloquent\Relations\Relation::getMorphedModel($event->getMorphClass())
You can simply define a type custom attribute inside the Event model:
use Illuminate\Database\Eloquent\Relations\Relation;
class Event
{
public function getTypeAttribute()
{
return class_basename($this->schedulable_type);
}
}
Then within the blade file, you can simply say:
<td>{{$event->type}}</td>

Soft delete on table

I just started using soft delete and I am not really sure how to do it, I am just following someone example and is still unsure how to do a proper soft delete. All I want is to delete the personal_info table but I keep on getting a no error message which make me at lost since I don't know what I am doing wrong, can someone help me? Thanks a lot
home.blade.php
<table class="table table-bordered">
<tr>
<th><strong><big>Name: </big></strong></th>
<th><strong><big>Action </big></strong></th>
</tr>
<td>
<tr>
#foreach($data as $value)
<tr>
<th>{{$value->Name}}</th>
<th><form action="{{ url('/home/'.$value->id.'/delete') }}" method="post">
<button>Delete</button>
</form></th>
</tr>
#endforeach
</tr>
</tr>
</table>
Controller:
public function delete($id = 0){
if ($id > 0){
personal_info::destroy($id);
}
return redirect("/home");
}
or should I do it this way?
public function delete($id){
$data = personal_info::find($id)->delete();
return redirect("/home");
}
personal_info model:
use Illuminate\Database\Eloquent\Model;
use Eloquent;
use SoftDeletes;
class personal_info extends Eloquent
{
protected $fillable = array('Name');
protected $table = 'personal_infos';
protected $primaryKey = 'id';
protected $dates = ['deleted_at'];
public function user_info1s() {
return $this->hasMany('App\user_info1','user_id');
}
Route: (not sure should I use DELETE instead)
Route::get('/home/{id}/delete', 'HomeController#delete');
There is no need to use delete on the method. try to change your function to this
public function delete($id){
personal_info::findOrFail($id)->delete();
return back();
}
Edit
The Route method and Form method must be the same.
Change
Route::get('/home/{id}/delete', 'HomeController#delete');
To
Route::post('/home/{id}/delete', 'HomeController#delete');
Controller Method
use Carbon\Carbon;
public function delete($id)
{
personal_info::find($id)->update([
'deleted_at' => Carbon::now()
]);
return redirect()->back();
}
home.blade.php
<table class="table table-bordered">
<tr>
<th><strong><big>Name: </big></strong></th>
<th><strong><big>Action </big></strong></th>
</tr>
<td>
<tr>
// Example of adjusting your query to support soft deletes
#php
$data = Some\Model::whereNotNull('deleted_at')->get();
#endphp
#foreach($data as $value)
<tr>
<th>{{$value->Name}}</th>
<th><form action="{{ url('/home/'.$value->id.'/delete') }}" method="post">
<button>Delete</button>
</form></th>
</tr>
#endforeach
</tr>
</tr>
</table>

Many to Many form binding

How to binding a input with many to many relationship data?
My relationship is: a Model has many Damages, and a Damage has many Models. in pivot table exists a price field.
I need populate a input with price data.
{{ Form::input('number', "prices[{$model->id}][{$damage->id}]") }}
My Model:
class Model extends \BaseModel {
public function damages()
{
return $this->belongsToMany('Damage', 'prices_damages', 'model_id', 'damage_id')
->withPivot('price')
->withTimestamps();
}
}
Pivot table
Schema::create('prices_damages', function(Blueprint $table)
{
$table->increments('id');
$table->integer('model_id')->unsigned();
$table->integer('damage_id')->unsigned();
$table->float('price')->nullable();
$table->timestamps();
});
Controller
/**
* Display a index dashboard page.
*
* #return \Illuminate\Http\Response
*/
public function getDamages()
{
$models = \Model::orderBy('order')->get();
$damages = \Damage::orderBy('order')->get();
return $this->render('Avarias', 'prices.damages', compact('models', 'damages'));
}
View:
<table class="table-striped table-header-rotated">
<thead>
<tr>
<th></th>
#foreach ($damages as $damage)
<th class="vertical"><div><span>{{ $damage->name }}</span></div></th>
#endforeach
</tr>
</thead>
<tbody>
#foreach ($models as $model)
<tr>
<td>{{ $model->fullname }}</td>
#foreach ($damages as $damage)
<td>
{{ Form::input('number', "prices[{$model->id}][{$damage->id}]", null, ['min' => 0, 'step' => 0.01]) }}
</td>
#endforeach
</tr>
#endforeach
</tbody>
</table>
You can't bind a collection (in the sense of laravel form model binding), so you can do this:
#foreach ($model->damages as $damage)
{{ Form::input('number', "damages[{$damage->id}][price]", $damage->pivot->price) }}
#endforeach

Resources