Error when trying to make relation in laravel - laravel

I'm trying to make a relationship in Laravel but always get the error:
Trying to get property 'nama_guru' of non-object (View: D:\xampp\htdocs\supervisi_digital\resources\views\ManagementSupervisi\index.blade.php).
Here is my code:
Dokumen Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Dokumen extends Model
{
protected $table = "dokumen";
protected $primarikey = "id";
protected $fillable =
[
'id', 'nama_guru', 'mapel', 'file', 'keterangan'
];
public function supervisi()
{
return $this->hasMany(Supervisi::class);
}
}
Supervisi Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Supervisi extends Model
{
protected $table = "supervisi";
protected $primarikey = "id";
protected $fillable =
[
'id', 'id_guru', 'id_mapel', 'id_keterangan', 'penilaian'
];
public function dokumen()
{
return $this->belongsTo(Dokumen::class);
}
}
Blade View
<table>
<thead>
<tr>
<th>#</th>
<th>NAMA GURU</th>
<th>MAPEL</th>
<th>KETERANGAN</th>
<th>PENILAIAN</th>
<th>ACTION</th>
</tr>
</thead>
<tbody>
#foreach ($dtSupervisi as $item)
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $item->dokumen->nama_guru }}</td>
<td></td>
<td></td>
<td></td>
</td>
</tr>
#endforeach
</tbody>
</table>
Controller
public function index()
{
$dtSupervisi = Supervisi::with('dokumen')->paginate(10);
return view('ManagementSupervisi.index', compact('dtSupervisi'));
}
I don't know what the problem is.

You need to define the foreign key and local key in your relationship.
public function dokumen()
{
return $this->belongsTo(Dokumen::class,'foreign_key','localkey');
}
so
public function dokumen()
{
return $this->belongsTo(Dokumen::class,'id_guru','id');
}

protected $fillable =
[
'id', 'id_guru', 'id_mapel', 'id_keterangan', 'penilaian', 'dokumen_id'
];
Use dokumen_id in Supervisi model and supervisi table after migrate database may be it's work

Related

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

Trying to get property of non-object error on page with laravel eloquent (showing vendors email)

I want to echo out vendors email, with {{$product->vendor->email}} but its not working.
The vendors and Products model database structure has been screenshot
<table id="example" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th width="10%">ID#</th>
<th>Product Title</th>
<th>Vendor In charge</th>
<th>Price</th>
<th>Category</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
#foreach($products as $product)
<tr>
<td>{{$product->id}}</td>
<td>{{$product->title}}</td>
<td>{{$product->vendor->email}}</td>
<td>{{$settings[0]->currency_sign}}{{$product->price}}</td>
<td>
{{\App\Category::where('id',$product->category[0])->first()->name}}<br>
#if($product->category[1] != "")
{{\App\Category::where('id',$product->category[1])->first()->name}}<br>
#endif
#if($product->category[2] != "")
{{\App\Category::where('id',$product->category[2])->first()->name}}
#endif
</td>
<td>
#if($product->status == 1)
Active
#elseif($product->status == 2)
Pending
#else
Inactive
#endif
</td>
<td>
</td>
</tr>
#endforeach
</tbody>
</table>
This is the vendor model and the ![database structure] https://i.postimg.cc/MHnwgHCz/vendormain.png
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class Vendors extends Authenticatable
{
use Notifiable;
public $table = "vendor_profiles";
protected $fillable = [
'name', 'gender', 'email', 'shop_name', 'photo', 'phone', 'password', 'fax', 'address', 'city', 'zip', 'current_balance', 'status', 'created_at', 'updated_at'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
];
public function product()
{
return $this->hasMany('App\Product', 'id');
}
}
This is the products model and the ![database structure] https://i.postimg.cc/W4F61ZpS/productmain.png
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = ['title', 'category', 'tags', 'description','sizes', 'price', 'previous_price', 'stock', 'feature_image', 'policy', 'featured', 'views', 'created_at', 'updated_at', 'status'];
public static $withoutAppends = false;
public function vendor()
{
return $this->belongsTo('App\Vendors', 'vendorid');
}
}
My Error:
Trying to get property of non-object
because you have invalid value (null) so just add condition to check it
<td>#if(is_null($product->vendorid)) No Vendor #else {{$product->vendor->email}} #endif</td>

How to access model function in view or blade file

I want to get interest amount which is multiple of amount and interest rate in a table "loan". I want to call the value from a table and used for display loan information.
I have tried using mutators in which case gives same error as mentioned below
Loan.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Loan extends Model
{
protected $fillable = ['amount', 'interest', 'status', 'member_id', 'loan_type_id', 'interest_type_id', 'loan_payment_type_id'];
public function getInterestAmountAttribute()
{
return $this->amount * $this->interest;
}
public function member()
{
return $this->belongsTo(Member::class, 'member_id', 'id');
}
}
loan.blade.php
<table class="table table-stripped">
<thead>
<tr>
<th>Loan Id</th>
<th>Amount</th>
<th>Interest</th>
<th>Interest Amount</th>
<th>Interest Type</th>
<th>Loan Type</th>
<th>Status</th>
<th>Payment Type</th>
<th>Member</th>
<th>Action</th>
</tr>
#foreach($loanData as $key=>$loan)
<tr>
<td>{{++$key}}</td>
<td>{{$loan->amount}}</td>
<td>{{$loan->interest}}</td>
<td>{{ $loan->interest_amount}}</td>
<td>{{$loan->interesttype->interest_type}}</td>
<td>{{$loan->loantype->loan_type}}</td>
<td align="center">
<span class="bg bg-primary" style="border-radius: 10px;padding:2px 5px">{{$loan->status}}</span>
<form action="{{route('update-loan-status')}}" method="post">
{{csrf_field()}}
<input type="hidden" name="criteria" value="{{$loan->id}}"/>
#if($loan->status== 1)
<button class="btn btn-success btn-xs" name="paid"><i class="fa fa-check"></i></button>
#endif
#if($loan->status== 0)
<button class="btn btn-danger btn-xs" name="unpaid"><i class="fa fa-close"></i></button>
#endif
</form>
</td>
<td>{{$loan->paymentmethod->method}}</td>
<td>{{$loan->member->name}}</td>
<td>
Delete
Edit
</td>
</tr>
#endforeach
</thead>
</table>
{{$loanData->links()}}
This gives the following error:
Method Illuminate\Database\Eloquent\Collection::links does not exist.
when I remove brackets
<td>{{$loan->getInterest}}</td>
the error is
App\Loan::getInterest must return a relationship instance.
LoanController.php
<?php
namespace App\Http\Controllers\Backend;
use App\Http\Controllers\Controller;
use App\Loan;
use App\Interest;
use App\LoanPaymentMethod;
use App\Member;
use App\Loantype;
use DB;
class LoanController extends Controller
{
protected $_backendPath = 'backend.';
protected $_pagePath = 'backend.pages.';
protected $_data = [];
public function index()
{
$loanData = Loan::orderBy('id', 'desc')->get();
$loanData = Loan::paginate(10);
$loanData = Loan::all();
$memberData = Member::all();
$loantypeData = Loantype::all();
$paymentmethodData = LoanPaymentMethod::all();
$interestData = Interest::all();
$this->_data['loanData'] = $loanData;
//$results = Loan::with('member')->get();
//$dat->loan = Loan::with('member')->get();
//$loan = Member::find($memberData)->loan;
return view($this->_pagePath . 'loan.loan', $this->_data);
//$userData = DB::table('members')->get();
//return view('home',compact('userData'));
}
}
Define your function as accessor in your Loan.php :
public function getGetInterestAttribute()
{
return $this->amount * $this->interest;
}
Now you can access it , like this :
<td>{{ $loan->get_interest }}</td>
The right way to call an Accessor,
public function getModifiedInterestAttribute() // first get then ModifiedInterest then Attribute
{
return $this->amount * $this->interest;
}
Then you can call the Accessor like below,
<td>{{$loan->modified_interest }}</td>
You can see this for more details : https://laravel.com/docs/5.8/eloquent-mutators#defining-an-accessor
You should append that variable in model data Like
class Loan extends Model
{
protected $appends = ['interest'];
}
Your accessor should like
public function getInterest()
{
return $this->amount * $this->interest;
}
Access in blade file as you use above
<td>{{$loan->interest}}</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>

Laravel view won't loop model even though it is populated

I'm creating a web based interface for my dovecot database.
I can get a list of all the virtual domains in the database and the number of emails and aliases easily enough.
But when I try to load a page to list the emails under a specific domain, it goes weird.
Three simple models:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class VirtualDomain extends Model
{
public function emails()
{
return $this->hasMany('App\VirtualUser', 'domain_id');
}
public function aliases()
{
return $this->hasMany('App\VirtualAlias', 'domain_id');
}
}
class VirtualUser extends Model
{
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
];
}
class VirtualAlias extends Model
{
//
}
My default controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\VirtualDomain;
use App\VirtualUser;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* #return \Illuminate\Http\Response
*/
public function index()
{
return view('home', [
'domains' => VirtualDomain::all(),
]);
}
public function domain($name)
{
$domain = VirtualDomain::where('name', $name)->first();
return view('domain', [
'domain' => $domain,
'emails' => VirtualUser::where('domain_id', $domain->id),
]);
}
}
and a couple of simple blades
home.blade.php
<p>
{{ $domains->count() }} domains
</p>
<table class="table-summary">
<thead>
<tr>
<th>name</th>
<th>emails</th>
<th>aliases</th>
<th class="table-summary-options">options</th>
</tr>
</thead>
<tbody>
#foreach ($domains as $domain)
<tr>
<td><a title="view emails for this domain" href="domain/{{ $domain->name }}">{{ $domain->name }}</a></td>
<td>{{ $domain->emails->count() }}</td>
<td>{{ $domain->aliases->count() }}</td>
<td class="table-summary-options"><a class="ui-action" title="remove this domain" href=""><img src="/img/ui/remove.png" alt="remove"></a></td>
</tr>
#endforeach
</tbody>
</table>
and domain.blade.php
<p>
<< - {{ $domain->name }} - {{ $emails->count() }} emails
</p>
<table class="table-summary">
<thead>
<tr>
<th>email</th>
<th class="table-summary-options">options</th>
</tr>
</thead>
<tbody>
#foreach ($emails as $email)
<tr>
<td><a title="view aliases for this domain" href="email/{{ $email->email }}">{{ $email->email }}</a></td>
<td class="table-summary-options"><a class="ui-action" title="remove this email" href=""><img src="/img/ui/remove.png" alt="remove"></a></td>
</tr>
#endforeach
</tbody>
</table>
The view outputs the correct number of emails under the domain with {{ $emails->count() }} - but the#foreach ($emails as $email)` does not loop.
When I modify the blade to simple use the emails from the domain variable ({{ $domain->emails->count() }} and #foreach ($domain->emails as $email)), I get the right count and the list is populated correctly.
What's making it go wrong when using the emails variable?
You have to make a small change for it to work
public function domain($name)
{
$domain = VirtualDomain::where('name', $name)->first();
return view('domain', [
'domain' => $domain,
'emails' => VirtualUser::where('domain_id', $domain->id)->get(),
]);
}
Without ->get() you will get a query builder instance while with get() will return a collection. In the foreach loop a collection can be iterated while a query builder instance can't be.
Hope this helps

Resources