How to access model function in view or blade file - laravel

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>

Related

Error when trying to make relation in 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

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>

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

Accessing and displaying pivot table data

Theory:
Users can attend many events and many events can be attended by many users. Therefore, I have two many-to-many relationships within my models, linking to a pivot table (event_user). On attending each event, I want to be able to access the pivot table data (event_user) to see if they're already attending.
event_user:
--id
--event_id
--user_id
For example, my seed data is:
user 1 attending both event 2 and 3. I want to be able to show this within a view.
The closest I have got is (logically):
public function index()
{
$id = Auth::user()->id;
$attending = myApp\Event::find($id)->event;
var_dump($attending); **But this var_dump returns NULL, but $id returns the correct ID.**
$events = myApp\Event::all();
$this->layout->content = View::make('events.index')->with('events', $events);
}
My aim is to disable the 'attend' button, on any event where they are already attending, only leaving the attend-able events available!
Any help would be hugely appreciated. Thank you in advance.
Any additional code which you may find necessary:
Events Model:
<?php
namespace myApp;
use Eloquent;
class Event extends Eloquent {
public function consultant()
{
return $this->belongsToMany('myApp\Consultant');
}
public function location()
{
return $this->belongsToMany('myApp\Location');
}
public function user()
{
return $this->belongsToMany('myApp\User');
}
}
User Model:
<?php
namespace myApp;
use Eloquent;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
public function event()
{
return $this->belongsToMany('Event');
}
public function practice()
{
return $this->belongToMany('Practice');
}
index.blade.php (showing the event list)
<div class="panel panel-success">
<!-- Default panel contents -->
<div class="panel-heading"><strong>Events</strong></div>
<!-- <div class="panel-body">
</div> -->
<!-- Table -->
<table class="table">
<thead>
<tr>
<th>Title</th>
<th>Date</th>
<th>Presenter</th>
<th>Location</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach($events as $event)
<tr>
<td>{{ $event->title }}</td>
<td>{{ date("j F Y", strtotime($event->date)) }}</td>
<td>{{ $event->consultant()->first()->title }} {{ $event->consultant()->first()->surname }}</td>
<td>{{ $event->location()->first()->address_1 }}</td>
<td><button type="button" class="btn btn-info">Attend</button></td>
</tr>
#endforeach
</tbody>
</table>
</div>
</table>
I think you're going about this the wrong way, that or I have misunderstood.
Firstly, you're trying to find an event with the same primary key as the currently authenticated user, which isn't correct, although it's an easy hole to fall down.
$id = Auth::user()->id;
$attending = myApp\Event::find($id)->event;
// equivalent of: SELECT * FROM `events` WHERE `id` = ?
Instead you'll want to do this
$id = Auth::user()->id;
$attending = myApp\Event::where('user_id', $id)->get();
// equivalent of: SELECT * FROM `events` WHERE `user_id` = ? (user_id insted of events.id)
That being said, surely the user events can be accessed by just calling the event property on the auth user?
$user = Auth::user();
$attending = $user->event;
To take this one step further, and make it so that you can check inside the foreach loop, you could advanced the above code to look like the following
$user = Auth::user();
$attending = $user->event->lists('id');
This will make an array of ids from the returned events that you need to assign to the view
$this->layout->content = View::make('events.index', array('events' => $events, 'attending' => $attending));
Now you can freely access it in your foreach
#foreach($events as $event)
<tr>
<td>{{ $event->title }}</td>
<td>{{ date("j F Y", strtotime($event->date)) }}</td>
<td>{{ $event->consultant()->first()->title }} {{ $event->consultant()->first()->surname }}</td>
<td>{{ $event->location()->first()->address_1 }}</td>
<td>
#if (!in_array($event->id, $attending))
<button type="button" class="btn btn-info">Attend</button>
#endif
</td>
</tr>
#endforeach
Also, seeing as Event is a reserved Alias (unless you've modified the config, which I wouldn't recommend), you'll want to specify the namespace in the relationship declaration within User
public function event()
{
return $this->belongsToMany('myApp\Event');
}
As a final point, it's not an issue as such, but in my own code I try to name relationships that have the potential to return multiple objects in the plural, so it would be public function events();.

Resources