I have a relationship in my models with foreing keys, protected table.
This is my models:
Lot.php:
<?php
namespace App;
class Lot extends Model
{
protected $table = 'auct_lots_full';
protected $primaryKey = 'lot_id';
public function comments()
{
return $this->hasMany(Comment::class,'lot_id', 'lot_id');
}
}
Than related model Comment.php:
<?php
namespace App;
class Comment extends Model
{
public function lot()
{
return $this->belongsTo(Lot::class, 'lot_id', 'lot_id');
}
}
In my view I try to do this:
#foreach ($comments as $comment)
<dt>{{ $comment->lot }}</td>
#endforeach
It result this:
{"lot_id":391959148,"date":"2017-05-21","company":"MITSUBISHI","model_year_en":2005"}
Than in view I need to get only company information and I do this:
#foreach ($comments as $comment)
<td> {{ $comment->lot->company }}</td>
#endforeach
this result Error:
Trying to get property of non-object
I try to do this:
#foreach ($comments as $comment)
<td>
#foreach($comment->lot as $lot)
{{ $lot->company }}
#endforeach
</td>
#endforeach
And it also gives error:
Trying to get property of non-object
How can I get $comment->lot->company work?
Thanks, to Snapey from laracasts
when you do this
#foreach ($comments as $comment)
<td> {{ $comment->lot->company }}</td>
#endforeach
you are relying on EVERY comment having a lot and every lot having a company
You can use this to protect against empty properties
#foreach ($comments as $comment)
<td> {{ $comment->lot->company or '---'}}</td>
#endforeach
Then the loop will continue even if the lot does not have company
Related
I have this very basic setup...
Users.php (Laravel Livewire component)
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\User;
class Users extends Component
{
public $users;
public function render()
{
$this->users = User::orderBy('name', 'asc')->get();
return view('livewire.users');
}
}
users.blade.php
#foreach ($users as $user)
<div>{{ $user }}</div>
<hr />
#foreach
However, it is throwing the exception Illuminate \ Contracts\View\ViewCompilationException with the following error:
Malformed #foreach statement.
Did I miss something? What does this error mean?
You need to close your #foreach statement with #endforeach before starting new foreach. Same applies for #if #endif or any other Blade directives.
#foreach ($users as $user)
<div>{{ $user }}</div>
<hr />
#endforeach
Reference: https://laravel.com/docs/9.x/blade#loops
I'm new to laravel. I want to access the products belongs to the category. There is One-to-Many relation between them. To get this data I created a function inside ProductsController named getCtgProducts() to do just that.
I know it a bad practice to query a database straight from views, hence I am writing the database query in the controller and trying to access it inside the blade.
Can someone tell me what I'm doing wrong?
What is the proper way to access the controller function inside the blade view? I'm using Laravel Framework v9.7.0
#foreach ($ctgs as $ctg)
<h1> $ctg->name </h1> // -- It is working. Showing the correct ctgs names
<div class=container>
#if (isset($products))
#foreach ({{ App\Http\Controllers\ProductsController::getCtgProducts($ctg->id) }} as $product)
<h1> $product->name </h1>
#endforeach
#endif
</div>
#endforeach
ProductsController class
<?php
namespace App\Http\Controllers;
use App\Models\Ctg;
use App\Models\Product;
class ProductsController extends Controller
{
public function index(Request $request)
{
$products = Product::all();
$ctgs = Ctg::all();
return view('ui\welcome', compact('products', 'ctgs'));
}
public static function getCtgProducts(){
$ctgProducts = DB::table('products')->where('ctg_id', $ctgId);
return $ctgProducts;
}
}
Calling controller from blade is bad practice
move your getCtgProducts() method logic to Category Model:
public function getCtgProducts(){
$ctgProducts = DB::table('products')
->where('ctg_id', $this->id)->get();
return $ctgProducts;
}
Blade file:
#foreach ($ctgs as $ctg)
<h1> $ctg->name </h1> // -- It is working. Showing the correct ctgs names
<div class=container>
#foreach ($ctg->getCtgProducts() as $product)
<h1> $product->name </h1>
#endforeach
</div>
#endforeach
Better way:
Since there's one-to-many relationship
in Category Model you should have a relationship method:
public function products() {
return $this->hasMany(Product::class);
}
Blade:
#foreach ($ctgs as $ctg)
<h1> $ctg->name </h1> // -- It
is working. Showing the correct ctgs
names
<div class=container>
#foreach ($ctg->products as
$product)
<h1> $product->name </h1>
#endforeach
</div>
#endforeach
I am working on an assignment for Uni however I've ran into a snag paginating my comments field. I have put my Controller, Model and View bellow(in that order)
<?php
namespace App\Http\Controllers;
use App\Comment;
use Illuminate\Http\Request;
class CommentController extends Controller
{
const COMMENTS_PER_PAGE = 5;
public function index () {
$comments = Comment::paginate (self::COMMENTS_PER_PAGE);
return view ('index') -> with (['comments' => $comments]);
}
public function create()
{
//
}
public function store(Request $request)
{
//
}
public function show(Comment $comment)
{
//
}
public function edit(Comment $comment)
{
//
}
public function update(Request $request, Comment $comment)
{
//
}
public function destroy(Comment $comment)
{
//
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public static function paginate(int $COMMENTS_PER_PAGE)
{
}
}
{{--#extends('layout.master)--}}
{{--#section('content')--}}
<div class="container main-table">
<div class="box">
<h1 class="title">Guestbook Comments</h1>
#if (count ($comments) > 0)
<table class="table is-striped is-hoverable">
<thead>
<tr>
<th>User</th>
<th>Comment</th>
<th>Date</th>
<th>Likes</th>
</tr>
</thead>
<tbody>
#foreach ($comments as $c)
{{--declaring the comments--}}
<tr>
<td>{{ $c -> name }}</td>
<td>{{ $c -> comment }}</td>
<td>{{ $c -> created_at -> format ('D jS F') }}</td>
<td>{{ $c -> likes }}</td>
</tr>
#endforeach
</tbody>
</table>
{{--looking at pagination--}}
{{ $comments -> links() }}
#else
<div class="notification is-info">
<p>
The Guestbook is empty. Why not add a comment?
</p>
</div>
#endif
</div>
</div>
{{--#endsection--}}
I managed to get it to display the comments before changing to pagination. After doing this I ran into issues getting it to display. I don't get an error I just get a blank page as if nothing is wrong. It doesn't show any of my headings or text that is not from my comments table.
Has anyone got any ideas about why this is?
Any help would be greatly appreciated :D
Update 17:44 13/11/19
Just realised that the link was going to the wrong page but just now figured out that the count function is having and issue as it says that there is no relevant ARRAY ("Facade\Ignition\Exceptions\ViewException
count(): Parameter must be an array or an object that implements Countable (View: C:\XAMPP\htdocs\Assignment\resources\views\comment\comments.blade.php) ")
Does anyone know why this is?
I thought it would just list comments 1 by 1 up until it reads out 5 comments.
Any ideas on how to fix this? :)
change {{ $comments -> links() }} & try this
{!! $comments->render() !!}
I would recommend to paginate like this.
public function index () {
const COMMENTS_PER_PAGE = 5;
$comments = Comment::paginate(self::COMMENTS_PER_PAGE);
return view('index', compact('comments'))
->with('i', ($request->input('page', 1) - 1) * 5);
}
and also, change
{!! $comments->links() !!}
to
{!! $comments->render() !!}
{!! $comments->appends(Request::except('page'))->render() !!}
I want to show total count of the unit so I wrote {{ ($unit->unit_id)->count() }} to return the data.
blade.php
<tbody>
#foreach($developer as $key => $data)
<tr>
<td></td>
<td>{{$data->developer_name}}</td>
<td>
#foreach($data->projects as $key => $project)
{{ $project->project_name }}<br>
#endforeach
</td>
<td>
#foreach($data->projects as $key => $project)
#foreach($project->phase as $key => $phase)
#foreach($phase->unit as $key => $unit)
{{ ($unit->unit_id)->count() }}<br> //error
#endforeach
#endforeach
#endforeach
</td>
</tr>
#endforeach
</tbody>
UPDATE:
Unit.php Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Unit extends Model
{
//
protected $table="pams_unit";
protected $primaryKey="unit_id";
}
UnitController
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Unit;
use App\Developer;
class UnitByDeveloperController extends Controller
{
//
public function __construct()
{
$this->middleware('auth');
}
public function show(Request $request){
$dev_id = $request->input('dev_id');
$developer =Developer::where(function($query1) use($dev_id){
if($dev_id){
$query1
->where('id',$dev_id);
}
})
->active()
->paginate('8');
return view('reportlayout.unitByDeveloper',compact('developer'));
}
}
But, an error is showing :-
Call to a member function count() on integer
Anyone can help me to spot my mistake ?
Change this:
{{ ($unit->unit_id)->count() }}
To:
{{ $unit->count() }}
I want to display data from an eloquent relationship in my view but I seem to be doing something wrong. Here's my model relationship, controller and view
Product
class Product extends Model
{
protected $guarded = ['id'];
public function prices()
{
return $this->hasMany(Price::class, 'product_id');
}
}
Price
class Price extends Model
{
protected $guarded = ['id'];
public function product()
{
$this->belongsTo(Product::class);
}
}
HomeController
public function index()
{
$products = Product::with('prices')->get();
return view('home', compact('products'));
}
View
#foreach ($products as $product)
<tr>
<td>{{ $product->prices->date }}</td>
<td>{{ ucwords($product->name) }}</td>
<td>{{ $product->prices->cost }}</td>
</tr>
#endforeach
My view returns the error
Property [date] does not exist on this collection instance
How do i fix this error?
In hasMany relations you have a Collection as result, so you should have another foreach to access each Price. Try something like this:
#foreach ($products as $product)
#foreach ($product->prices as $price)
<tr>
<td>{{ $price->date }}</td>
<td>{{ ucwords($product->name) }}</td>
<td>{{ $price->cost }}</td>
</tr>
#endforeach
#endforeach