How to Call/Display Foreach Loop after Login - laravel

I had problem on calling page inside Foreach Loop.Although It is Okay before I click Login, but when I'd try to login,only the html tag where loaded and foreach loop cannot... On my HomeController extends Controller
public function index()
{
return view('pages.welcome');
}
on where I call welcome page. and inside of it which is foreach loop.
<div class="row">
<div class="col-md-8">
#foreach ($posts as $post)
<div class="post">
<h3>{{ $post->title }}</h3>
<p>{{ substr($post->body, 0,300) }}
{{ strlen($post->body) > 300 ? "..." : " " }}</p>
Read More...
</div>
<hr>
#endforeach
</div>
</div>
And I think the problem is my route:
Route::get('/home', 'HomeController#index');

You haven't passed the $posts variable to the view.
Change
public function index()
{
return view('pages.welcome');
}
To something like this:
public function index()
{
$posts = \App\Post::all(); //Assuming your model is called "Post" in the App namespace
return view('pages.welcome', compact('posts'));
}
NOTE: compact('posts') is just a shortcut for ['posts'=>$posts]

Related

Show category posts in Laravel is not working

I want to show posts that are in a category by clicking on them, but when I click on a category,$articles in category.blade.php returns null.
$articles should return articles that have a specific category
this is my index.blade.php:
<div class="tab-pane fade" id="show-categories" role="tabpanel">
<h6 class="sidebar-title">Categories</h6>
<div class="row link-color-default fs-14 lh-24">
#foreach($categories as $category)
<div class="col-6">
<a href="{{ route('cms.category', $category->id) }}">
{{ $category->name }}
</a>
</div>
#endforeach
</div>
</div>
category.blade.php:
#extends('layouts.app')
#section('content')
#forelse ($articles as $article)
<h1>{{$article->title}}</h1>
#empty
<span>array is empty</span>
#endforelse
#endsection
router:
Route::get('cms/categories/{category}', [articlesController::class, 'category'])->name('cms.category');
and articlesController:
public function category(Category $category)
{
return view('cms.category')
->with('category', $category)
->with('articles', $category->articles()->searched()->simplePaginate(3))
->with('categories', Category::all())
->with('tags', Tag::all());
}
Please, don't forget to define the relationship from Category to Article on your model. Like: one category has many articles. For example:
On your Category.php model:
public function articles()
{
return $this->hasMany(Article::class);
}
Then on your, controller, you may call the relationship like this way:
public function category(Category $category)
{
$articles = Category::with("articles")->where("id", $category->id)->simplePaginate(3);
return view('cms.category')
->with('category', $category)
->with('articles', $articles)
->with('categories', Category::all())
->with('tags', Tag::all());
}
Please share the model file and second I prefer to write the category method in a different way.
public function category($category_id)
{
try {
$articles= Article::where('id', $category_id)->get();
return view('cms.category', $articles);
} catch (\Throwable $th) {
Log::error($th->getMessage());
}
}
Let me know if you still face any issue. Try to use dd $articles ..

Get objects of related tables from a collection laravel

I want to pass the result of a searching action but I am facing a problem because it is returning an array and from that all the relationships of the table are not working
result view. For this I can only access the data on my table not the related data through relationships
#extends('layouts.app')
#section('content')
#foreach ($result as $object)
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h3>Details for the animal</h3>
</div>
<div class="card-body">
<div class="col-12">
<p><strong>Id: </strong>{{ $object->id }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
#endforeach
#endsection
Here is my controller
<?php
namespace App\Http\Controllers;
use App\Animal;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class SearchController extends Controller
{
public function index()
{
Animal::all();
return view('search.index');
}
public function postSearch(Request $request)
{
$serial_number = $request->input('search');
$this->getResult($serial_number);
return redirect()->route('result',$serial_number);
}
public function getResult($serial_number){
$result = DB::table('slaughters')->where(function ($query) use ($serial_number) {
$query->where('id','LIKE',"%$serial_number%");
})->latest()->get();
return view('search.result', ['result'=>$result]);
}
}
And my routes
Route::get('/search','SearchController#index')->name('search');
Route::post('/get','SearchController#postSearch');
Route::get('/search/{result}','SearchController#getResult')->name('result');
I would like to access data from the table related to this one too. What am to do
Slaughter model
class Slaughter extends Model
{
protected $guarded = [];
public function user(){
return $this->belongsTo(User::class);
}
public function animal(){
return $this->belongsTo(Animal::class);
}
You must create model Slaughter and define relations.
And then you can get result:
public function getResult($serial_number)
{
$result = Slaughter::with(['name_of_relation_1', 'name_of_relation_2'])->latest()->get();
return view('search.result', ['result'=>$result]);
}
In your Controller:
use App\Slaughter;
public function getResult($serial_number) {
$result = Slaughter::where('id', 'like', "%{$serial_number}%")
->with('user', 'animal')
->latest()
->get();
return view('search.result', compact('result'));
}
In your view you can then access the relationships like so:
{{ $object->user }}
{{ $object->animal }}

Undefined variable when trying to use two loops

I have two functions
whatsnew()
and
perfume()
both has its own #foreach in different sub folders which i show them in one page.
problem is if one #foreach works the other show an error undefined variable
ps- this is my first time posting a question in SO .. sorry if its sloppy..
ProductController.php
//to show last 5 latest items
public function whatsnew(){
$cat_new = products::orderBy('id', 'desc')->take(5)->get();
return view('/home', compact('cat_new'));
}
//to show category
public function perfume(){
$perfume = products::where('category','LIKE','perfume')->get();
return view('/home', compact('perfume'));
}
Web.blade.php
Route::get('/', [
'uses' => 'ProductController#whatsnew',
'as' => 'db.whatsnew']);
Route::get('/', [
'uses' => 'ProductController#perfume',
'as' => 'db.perfume']);
perfume.blade.php
#foreach($perfume as $perfume_cat)
whatnew.blade.php
#foreach($cat_new as $row)
It looks like you are passing only 1 collection back to the view each time, which is probably why one or the other works.
If you change this:
public function whatsnew(){
$cat_new = products::orderBy('id', 'desc')->take(5)->get();
return view('/home', compact('cat_new'));
}
public function perfume(){
$perfume = products::where('category','LIKE','perfume')->get();
return view('/home', compact('perfume'));
}
to this:
public function whatsNew(){
$cat_new = products::orderBy('id', 'desc')->take(5)->get();
return $cat_new; // return the collection
}
public function perfume(){
$perfume = products::where('category','LIKE','perfume')->get();
return $perfume; // return the collection
}
// Create a new index function and pass both collections to your view
public function index() {
return view('index', [
'cat_new' => $this->whatsNew(),
'perfume' => $this->perfume(),
]);
}
Your web routes file can be:
Route::get('/', 'ProductController#index')->name('product.index');
Your index.blade.php
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<ol>
#foreach( $cat_new as $new )
<li>{{ $new->foo }}</li>
#endforeach
</ol>
</div>
</div>
<div class="card">
<div class="card-body">
<ol>
#foreach( $perfume as $p )
<li>{{ $p->bar }}</li>
#endforeach
</ol>
</div>
</div>
</div>
</div>
</div>
where foo and bar are whatever columns you are after.
//merge become one
public function perfume(){
$perfume = products::where('category','LIKE','perfume')->get();
$cat_new = products::orderBy('id', 'desc')->take(5)->get();
return view('/home', compact('perfume', 'cat_new'));
}

Get the user name and comment with article id in Laravel

I have 3 tables users, comments, and articles. I have a route like this:
Route::get('/article/{id}', 'ArticlesController#view');
What I want is when I accessing that route I will get User Name and their comment in this article id.
so here's my view function in ArticlesController:
public function view($id){
$article = Article::with('comments')->find($id);
return view('front.single',compact('article'));
}
and here's my single.blade.php code:
<div class="single-grid">
#section('content')
<h1>{{ $article->title }}</h1>
<p>{{ $article->content }}</p>
#show
</div>
<div class="comment-list">
#foreach($article->comments as $comment)
<ul class="comment-list">
<div class="comment-grid">
<img src="/images/avatar.png" alt=""/>
<div class="comment-info">
<h4>{{ $comment->user->name }}</h4>
<p>{{ $comment->comment }}</p>
<h5>{{ $comment->created_at->diffForHumans() }}</h5>
Reply
</div>
<div class="clearfix"></div>
</div>
</ul>
#endforeach
</div>
I'm not sure what how to do it since it gives me error like this:
"Call to undefined relationship [comment] on model [App\User]."
I already define the relation in each model. here's my articles model:
public function comments(){
return $this->hasMany(Comment::class);
}
public function user(){
return $this->belongsTo(User::class);
}
My comment model:
public function article(){
$this->belongsTo(Article::class);
}
public function user(){
$this->belongsTo(User::class);
}
and here's my User model:
public function articles(){
return $this->hasMany(Article::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
public function publish(Article $article){
$this->articles()->save($article);
}
here's my table structure:
-users(id,name,email,password,remember_token,created_at,updated_at)
-comments(id,user_id,article_id,comment,created_at,updated_at)
-articles(id,user_id,title,content,created_at,updated_at)
so how can I can User Name just by using this route? thanks.
on Your Comment Model, You need to replace articles to article
public function article(){
$this->belongsTo(Article::class);
}
also, if you want to get user specific comments, than you need to change your controller action code from
$article = Article::with('user.comment')->find($id) to
$article = Article::with('user.comments')->find($id);
I think that your issue comes from the use of compact function : an array is passed to the view instead of an object.
Can you try it like this :
// Controller
public function view($id) {
$article = Article::findOrFail($id);
return view('front.single', $article);
}
<!-- View -->
#foreach($article->comments as $comment)
{{ $comment->user->name }}
{{ $comment->comment }}
{{ $comment->created_at->diffForHumans() }}
#endforeach

Is there a more efficient way for grabbing the count of a model within the view? Laravel

I have Images. Each image has comments, and each comment has likes. In my view I'm wanting to display the number of likes a comment has by doing something like this:
#foreach ($images as image)
<img href="$image->url">
<div class="comment-box">
#foreach ($image->comments as $comment)
<div class="comment">
<span class="comment-owner">{{ $comment->owner()->name }}</span> {{ $comment->body }}
<div class="likes">
{{ $comment->likes()->count() }} // ** HERE IS MY N+1 PROBLEM **
</div>
</div>
#endforeach
</div>
#endforeach
However now I'm fetching a query each time there is a comment. There could be hundreds of comments on a page, so id be getting hundreds of queries just to find the count() for likes.
I believe there is a way you can grab the count in a controller by doing something like
DB::raw('count(*) as like_count')
but I do not know how to implement this in my situation. Can I put this kind of thing in my model so that I can always call something like {{ $comment->likes()->like_count }}? How can I make $comment->likes->count() work without having the N+1 problem?
Here is some more code:
Media Model
class Media extends Eloquent {
public function comments()
{
return $this->hasMany('Comment');
}
}
Comment Model
class Comment extends Eloquent {
public function media()
{
return $this->belongsTo('Media');
}
public function likes()
{
return $this->hasMany('Like');
}
}
Like Model
class Like extends Eloquent {
public function comment()
{
return $this->belongsTo('Comment');
}
}
My controller
public function imageViewer($id)
{
$images = Media::with(['comments' => function($query) {
$query->with('likes');
}])->where('resource_id', $id)->simplePaginate(1);
return View::make('image-viewer', compact('images'));
}
Why don't you just use blade's count like this count($comment->likes) assuming that $comment->likes gets the list of likes for a comment
#foreach ($images as image)
<img href="$image->url">
<div class="comment-box">
#foreach ($image->comments as $comment)
<div class="comment">
<span class="comment-owner">{{ $comment->owner()->name }}</span> {{ $comment->body }}
<div class="likes">
{{ count($comment->likes) }}
</div>
</div>
#endforeach
</div>
#endforeach
Thanks to #lukasgeiter for pointing out a mistake in the comments

Resources