rahul singh
rahul singh

Reputation: 41

laravel eloquent relationship hasmany query

i am trying to implement a sql query

select * from user,comments where comments.user_id= user.id

so i create a getcomments method on my user model with following code

public function comments(){return $this->hasMany('Comments')}

and now am accessing the data by

$data = User::find(1)->comments;

but it gave me the data only from comments table (not user and comments ) how can i do this

Upvotes: 2

Views: 7842

Answers (3)

Peter Kota
Peter Kota

Reputation: 8340

First find a user. Then access all user data, and all comments of user.

$data = User::find(1);
//or you can use eager loading for more performance. thanks for @Özgür Adem Işıklı
$data = User::with('comments')->find(1);

//access user data
$data->id;
$data->email; //etc.

//user's comments:
foreach($data->comments as $comment) {
    //access comment detail
    $comment->id;
    $comment->title;
}

Upvotes: 1

patricus
patricus

Reputation: 62248

The Eloquent ORM follows the Active Record pattern. It is a slightly different way to think about modeling and interacting with your data when you come from writing pure sql statements.

Setting up the comments relationship is a good step. Now you need to think about how you interact with your data.

You can get all the information with the following statement:

$user = User::with('comments')->find(1);

With this statement, all of the user information is loaded into the $user object, and all of the comment information is loaded into the $user->comments Collection attribute. This information can be accessed like so:

// get the info
$user = User::with('comments')->find(1);

// display some user info
echo $user->first_name;
echo $user->last_name;

// loop through the comment Collection
foreach($user->comments as $comment) {
    // display some comment info
    echo $comment->text;
}

The with('comments') section tells the query to eager load all the comments for the returned users (in this case, just the one with id 1). If you didn't eager load them, they would be lazy loaded automatically when you try to access them. The above code would work exactly the same without the with('comments'). Eager loading becomes more important when your loading multiple parent records, though, instead of just one, as it solves the N+1 problem. You can read about eager loading here.

Caution (the reason I added a new answer):

User::find(1)->with('comments')->get();, as otherwise suggested, is not going to provide the information you're looking for. This will actually end up returning all your users with their comments eager loaded. Here is why:

First, User::find(1) is going to return the one user with an id of 1, which is good. However, it then calls with('comments') on this model, which actually creates a new query builder instance for the users table. Finally, it calls get() on this new query builder instance, and since it doesn't have any constraints on it, it will return all the users in the table, with all the comments attached to those users eager loaded.

Upvotes: 5

You are fetching just comments of the user which you select by id. You should this;

User::find(1)->with('comments')->get();

Upvotes: 0

Related Questions