Laravel 5.2 Eager Loading with multiple level one to may relationship - php

I'm new to laravel and I'm using Laravel 5.2 I want to have all the comments of a particular post of a user. My tables are like :
User
-----
id
public function posts() {
$this->hasMany( 'App\Posts' )
}
Post
------
id
user_id
public function user() {
$this->belongsTo( 'App\User' )
}
public function comments() {
$this->hasMany( 'App\Comment' )
}
Comments
----------
id
post_id
public function post() {
$this->belongsTo( 'App\Post' )
}
Now what I want is to get all the post for a perticular user say the logged in user. I can get all the comments by the long way like :
$comments = [];
foreach( Auth::user()->posts as $post) {
foreach( $post->comments as $comment )
{
$comments[] = $comment->title
}
}
But I was wondering how to get the comments without making these loops using the relations only. Thanks in advance.

You can double the relationship from the existing user object:
$posts = \Auth::user()->posts()->with('comments')->get();
It should work for all levels.
In my project I have Organizations with Clients with a link table to Therapists, all multiple, and this works:
Organization::find(1)->clients()->with('therapists')->get();
so your case should work too. Let me know.

Essentially you want to eager load your data using with() and dot notation like so:
$user = User::with('posts.comments')->find(Auth::user()->id);
If you just want the comments, you can do:
$user = User::with('comments')->find(Auth::user()->id);
$comments = $user->comments();

Related

Retrieving data by other field than id in has many relations

I have a has many relation between models: post and category in laravel application. I've defined these relations as:
public function category() {
return $this->belongsTo('artSite\category');
}
public function posts() {
return $this->hasMany('artSite\post');
}
Now I'm trying retrieve posts belonging to the particular category which are derived in http request:
Route::get('posts/categories/{categoryName}','postsViewController#showPostGivenCategory')
Below I show my controller function (it does work fine!):
public function showPostGivenCategory($categoryName) {
$category = category::where('category_name','=',$categoryName)-first();
$posts = category::find($category->id)->posts;
return view('pages.homePage')->with('categories',$categories)with('posts',$posts);
}
In this solution I'm creating 2 queries. Is any possible way to create 1 query to retrieve posts of particular category in has many relation?
Something like that doesn't work:
$posts = category::where('category_name','=',$categoryName)->posts;
Could someone help me with this problem? I would be very grateful, greetings.
we can get rid of the second line :
$posts = Category::find($category->id)->posts;
So You can say :
$posts = Category::where('category_name','=',$categoryName)->first()->posts;

laravel multilevel relations

Is it possible to make a multi level relation query with Eloquent on a deeper level than 1 level? My tables look like this :
post_comments-> id|comment|post_id|user_id|...
post_comment_replies-> id|reply|post_comment_id|user_id|...
users-> id|name|....
user_data-> id|avatar|...
And so I want to ask is it possible to get the Comments for a Post with all the Replies and the User Data for the person who replied to a comment in 1 query with Eloquent.
This is how my Comments Model looks like:
class PostComment extends Model{
public function replies(){
return $this->hasMany(PostCommentAwnsers::class);
}
public function user() {
return $this->belongsTo(User::class);
}
public function userInfo(){
return $this->belongsTo(UserInfo::class,'user_id','user_id');
}}
public function index($id){
$posts = Post::find($id);
$postComments = PostComment::where('post_id','=',$id)->paginate(5);
return view('post.show',[
'post' => $post,
'postComments' =>$postComments
]);
}
And as I get all the user data for a Comment I want to get all the user data for the person who replied.
I am really sorry if this has been awnsered or documented somewhere else but I just can't seem to find the exact solution to this problem.
You should look for eager loading : https://laravel.com/docs/5.3/eloquent-relationships#eager-loading
if you want to get all posts and their comments :
$posts = Post::with('comment')->get();
and if you want all posts with comments and replies of the comments :
$posts = Post::with('comment.reply')->get();

Querying a Collection of One-to-Many Relationship

Suppose I have a User model and a Post model.
class Post extends Eloquent
{
}
There are many users, and each User has many Post. All Post belongs to a User.
class User extends Eloquent
{
public function posts()
{
return $this->hasMany('Post');
}
}
I know that I can get a single User with find().
$user = User::find(1);
I know that from a single User, I can get all their posts().
$posts = User::find(1)->posts;
However, suppose now I have multiple users.
$users = User::all();
I wish to access all the posts that this collection of users have. Something along the lines of
$posts = User::all()->posts;
This, of course, doesn't work. However, in theory, it should be functionally equivalent to
$posts = Post::all()
Is there a way to do something similar to the above in Laravel 4.2?
I do not want to use Post::all(). Reason being that it would not be what I want in a more complicated example that involves constraints on User.
$postsByMaleUsers = User::where('gender', '=', 'male')->posts;
Should get all the posts made by male users.
I am also aware that I could simply use a foreach loop.
foreach($users->posts as $post)
{
// Process result here.
}
However, suppose I am trying to return the results instead of processing the results. For example, I could have a public static function postsByMaleUsers() in the User model, and calling User::postsByMaleUsers() should return a collection of posts by male users only. In which case, the foreach loop would not suit me.
Eager load the posts, then use pluck and collapse to get a flat collection of posts:
$users = User::with('posts')->where('gender', 'male')->get();
$posts = $users->pluck('posts')->collapse();

How can i get all posts by a particular user in Laravel?

Try to get all post's by a user in application and show in a table with corresponding column , i tried with this way but showing exception : " Trying to get property of non-object " , how to solve it ?
public function usersPost(){
$uid = \Auth::user()->id;
$posts = DB::table('posts')->('user_id',$uid);
}
Here two table posts and users and user_id is foreign key of posts table .
Laravel allows you to relate models to each other. For instance, you can relate your Post model to your User model like this.
class User extends Eloquent {
public function posts() {
return $this->hasMany('Post');
}
}
After specifying that the User has many posts through a One-to-Many relationship, you can then simply call all of your user's posts.
$posts = User::find(user_id)->posts;
public function usersPost() {
$posts = DB::table('posts')->where('user_id', auth()->id())->get();
}
You need a where clause like this:
$posts = DB::table('posts')->where('user_id', $uid)->get();

Laravel lazy load optimisation

I want to load all my comments with one query, for now I have Forum Thread and Replies and comments for both, so I eager load comments seperatly.
$threads = Thread::with('comments');
$replies = Reply::with('comments');
may be something like:
Comment::loadFor([$threads, $replies]);
If you have declared relations in your Comment model for both then You may try this:
$comments = Comment::with('threads', 'replies')->get();
In this case, you need to create relation methods, i.e. threads and replies in your Comment model, for example:
public function replies()
{
return $this->hasMany('Reply', 'comment_id', 'id'); // Could be different
}
public function threads()
{
return $this->hasMany('Thread', 'comment_id', 'id'); // Could be different
}

Categories