Undefined property error when trying to use a relationship in Laravel - php

I have the following relation between a post and it's comments :
In the Post model :
public function comments()
{
return $this->hasMany('App\Comment', 'post_id');
}
In the Comment model :
public function posts()
{
return $this->belongsTo('App\Post', 'id'); // id is the primary key in posts table
}
The posts are returning without any issue in the below foreach loop, but whenever I try to use the relationship to bring the comments, I see the below error :
Foreach :
#foreach($topans as $topanswer)
<p> {{$topanswer->body}} </p>
<br>
#if(!empty($topanswer->comments))
#foreach($topans->comments as $topanscom)
<p>{{$topanscom->comment}} </p>
#endforeach
#endif
#endforeach
Error :
Undefined property: Illuminate\Database\Eloquent\Collection::$comments (View: C:\xampp\htdocs\sharp\resources\views\showPost.blade.php)
Am I missing something ?

Looks like you are trying to pull the entire collection's worth of answers in your inner foreach loop. The top level collection ($topans) is a collection of topanswers, and does not have a field comments since it is a collection.
Try to pull the second level topanswer's comments in that inner foreach loop:
#foreach($topanswer->comments as $topanscom)
Also, just as a side note, I think you've fallen into the trap of naming -- it might help to use a little bit more descriptive or different names, it would help you get out of trouble :)

Related

Trying to get property 'comments' of non-object (View: /Applications/AMPPS/www/zenit/resources/views/middleware.blade.php)

I try to get comments belonging to project, a special user has posted but get this error:
Trying to get property 'comments' of non-object (View: /Applications/AMPPS/www/zenit/resources/views/middleware.blade.php)
I created a foreach loop in middleware.blade.php as follows;
#foreach(Auth::user()->courses->comments as $comment)
In My Course model I created the hasManyThrough relationship as follows
public function comments()
{
return $this->hasManyThrough(Comment::class, Project::class, 'course_id', 'project_id', 'id', 'id');
}
My projects table has a course_id column, and my comments table has a project_id column
Is there anyone who could help me? Thanks in advance
First it'll be better if you give your belongsTo relation a singular name not plural, because it retrieves only 1 object:
public function course()
{
return $this->belongsTo(Course::class);
}
And also in some cases $user->course can be null, so it won't have comments, so just check that case before foreach loop
// in some blade template
#if(auth()->user()->course)
#foreach(auth()->user()->course->comments as $comment)
{{ $comment->id }}
#endforeach
#endif

Double foreach loop with where condition in laravel blade

I have relations like this
User->hasMany->reviews
Review->belongsTo->user
Review->hasMany->ReviewAnswer
ReviewAnswer->belongsTo->Review
Now I try to display answers for specific review. My reviewAnswer table looks like:
Id, review ID, text
But the problem is when I do that:
#foreach($user->reviews as $data)
#foreach($data->reviewAnswers->where('review_id', $data->id) as $answer)
{{$answer->text}}
#endforeach
#endforeach
Then reviews displays okay, but I get the same answers for every review. How to repair that?
Make sure to check if all the relationships are correct. In this example, I assume that your models are stored in your app folder.
First, your User model should have reviews
public function reviews() {
return $this->hasMany("App\Review", "user_id", "id");
}
Next, set up your Review model to have answers
public function answers() {
return $this->hasMany("App\ReviewAnswer", "review_id", "id");
}
Then this is how you'll get all users with their respective reviews and answers
$users = User::with("reviews.answers")->get();
Finally, peform the loop in your view
#foreach($users as $user)
#foreach($user->reviews as $review)
#foreach($review->answers as $answer)
#endforeach
#endforeach
#endforeach
Try using the hasManyThrough() option which the eloquent models provide you.
Link: Laravel Eloquent Relations
This means in your case you would add:
class User extends Model {
public function reviewAnswers(
return $this->hasManyThrough(ReviewAnswer::class,Review::class);
)
}
and then simply access it in blade as:
#foreach($user->reviewAnswers() as $reviewAnswer) {
{{$reviewAnswer->text}}
}

Trouble fetching data from 1 to 1 relationsip Laravel

I have set up two model with its row in table. And made a single form to fill both tables and it works perfectly
Tour.php
public function featuredImage()
{
return $this->hasOne('App\FeaturedImage');
}
tours table
id|name|content|featured_status
featuredImage.php
public function tour()
{
return $this->belongsTo('App\Tour');
}
Featured_images table
id|tour_id|path|name
Code in my controller to pass data to view.
$tours = Tour::where('featured', 1)->get();
return view('public.pages.index')
->withTours($tours);
Code in my view
#foreach($tours as $featured)
<div class="thumbnail">
<img src="{{$featured->featuredimage->path}}" alt="{{$featured->featuredImage->name}}">
</div>
<h4>{{$featured-name}}</h4>
#endforeach
The trouble is I'm not able to fetch featured images by writing
{{$featured->featuredimage->path}}
and the error is
Trying to get property of non-object
on the line {{$featured->featuredimage->path}}. I have used this method in my previous project and it had worked perfectly but it isn't going well in this one.
I tried replacing {{$featured->featuredimage->path}} with {{$featured->featuredImage->path}} but didn't worrked out.
Do this:
{{ $featured->featuredImage()->path }}
Also, you're creating a lot of additional queries here. You should use eager loading to solve N + 1 problem:
$tours = Tour::with('featuredImage')->where('featured', 1)->get();
And display data with:
{{ $featured->featuredImage->path }}

Laravel #foreach

I need to get each comment of news . Its working good for firstorFail() item
{{$news->comments()->firstOrFail()->name}}
But bring me empty result when im try this one with foreach:
#foreach($news->comments() as $comment)
{{$comment->name}}
#endforeach
The function firstOrFail will return exactly one comment. Seems like you actually want all comments? You should use this in your controller
$news->comments; // yeah that's it, it will load all comments
Also return news
return view('my.view', compact('news'));
Then use it in blade
#foreach($news->comments as $comment)
{{$comment->name}}
#endforeach
the line
$news->comments()
would require you to also call ->get() , because comments() will return the relation instead of the actual data.
This: $news->comments() bringing you query builder probably. So what you need is to ->get() for execute query like this:
#foreach($news->comments()->get() as $comment)
{{$comment->name}}
#endforeach
Edit
or as a #Roy Philips mentioned: $news->comments

How do I take related posts (by category) with Eloquent?

I have a question on how to fetch the related posts of a particular post by category using Eloquent. I know how to do it in pure MySQL but am sure Eloquent will have nicer alternative to it.
My tables are: posts categories post_category (pivot)
I have made the neccessary Eloquent connections, so I want to do something like: $post->categories()->posts()->exclude($post)->get().
Of course this won't work. I get an error on posts() because "Builder doesn't have a method posts()", but hopefully you get the idea. How would you do it with Eloquent?
It's hard to say what you want to achieve, bot probably you want to get:
Posts::whereIn('id', $post->categories()->lists('id'))->whereNot('id',$post->id)->get();
One of the confusing parts about Eloquent's relations is that the method on a model that defines the relation will bring back a relation object when called like you're calling it:
$posts->categories();
To return a collection of category models attached to your posts you should use something like this:
Post::find(primary key of post)->categories;
Or get all posts and iterate through the models individually:
$posts = Post::all();
foreach($posts as $post) {
$post->categories;
}
Here's a resource I found very helpful in learning to use Eloquent's relation methods: http://codeplanet.io/laravel-model-relationships-pt-1/
I was trying to get my related posts by category and searched on google and got here.
I made this, and it worked fine.
public function getSingle($slug){
$post = Post::where('slug', '=', $slug)->first();
$tags=Tag::all();
$categories=Category::all();
$related= Post::where('category_id', '=', $post->category->id)
->where('id', '!=', $post->id)
->get();
return view('blog.show')
->withPost($post)
->withTags($tags)
->withCategories($categories)
->withRelated($related);
}
In my view('blog.show')
$post->title
$post->content
//related posts
#foreach($related as $posts)
$posts->title
$posts->category->name
#endforeach
I don't know if this is the right way, but it works for me. I hope this helps someone
Why don’t you define a ‘relatedposts’ relation where search for posts with the same category id?
Then you can simply do $post->relatedposts...
You’re making it overcomplicated imo...
if you have multiple category (Pivot ex:RelPortfolioCategory)
Portfolio Model:
public function getCats(){
return $this->hasMany(RelPortfolioCategory::class,'portfolioID','id');
}
controller:
public function portfolioDetail($slug){
$db = Portfolio::where('slug' , $slug)->with('getCats')->firstOrFail();
$dbRelated = RelPortfolioCategory::whereIn('categoryID' , $db->getCats->pluck('categoryID'))->whereNot('portfolioID' , $db->id)
->with('getPortfolioDetail')->get();
return view('portfolioDetail' , compact('db' , 'dbRelated'));
}

Categories