Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Query relationship Eloquent

I have News model, and News has many comments, so I did this in News model:

public function comments(){     $this->hasMany('Comment', 'news_id'); } 

But I also have field trashed in comments table, and I only want to select comments that are not trashed. So trashed <> 1. So I wonder is there a way to do something like this:

$news = News::find(123); $news->comments->where('trashed', '<>', 1); //some sort of pseudo-code 

Is there a way to use above method or should I just write something like this:

$comments = Comment::where('trashed', '<>', 1)     ->where('news_id', '=', $news->id)     ->get(); 
like image 348
Vuk Stanković Avatar asked Nov 17 '13 21:11

Vuk Stanković


People also ask

Why we use whereHas in Laravel?

whereHas() works basically the same as has() but allows you to specify additional filters for the related model to check.

What is eloquent query?

Eloquent is an object relational mapper (ORM) that is included by default within the Laravel framework. An ORM is software that facilitates handling database records by representing data as objects, working as a layer of abstraction on top of the database engine used to store an application's data.

How do you do an eloquent query?

The first method to get the query of an Eloquent call is by using the toSql() method. This method returns the query without running it – good if you don't want to alter data and only get the query – but this method doesn't show the whole query if your query is more complex or if there are sub-queries.

What is with () in Laravel?

with() function is used to eager load in Laravel. Unless of using 2 or more separate queries to fetch data from the database , we can use it with() method after the first command. It provides a better user experience as we do not have to wait for a longer period of time in fetching data from the database.


2 Answers

Any of these should work for you, pick the one you like the most:

  1. Eager-loading.

    $comments = News::find(123)->with(['comments' => function ($query) {     $query->where('trashed', '<>', 1); }])->get(); 

    You can inject the parameter to query function by use($param) method, that allows you to use dynemic query value at runtime.

  2. Lazy-loading

    $news = News::find(123); $comments = $news->comments()->where('trashed', '<>', 1)->get(); 

I couldn't help but notice, though, that what you're probably trying to do is handle soft deleting, and that Laravel has built-in functionality to help you with that: http://laravel.com/docs/eloquent#soft-deleting

like image 106
rmobis Avatar answered Sep 26 '22 03:09

rmobis


rmobis's answer was what I needed, but it throws an error in current Laravel 5. You have to use it as an associatve array now:

$comments = News::find(123)->with(     ['comments' => function ($query) {$query->where('trashed', '<>', 1);}] ); 

Took me some time to figure it out, hope this will help others.

Read more in Laravel's Docs (5.6): https://laravel.com/docs/5.6/eloquent-relationships#querying-relations

like image 20
glnemeth Avatar answered Sep 23 '22 03:09

glnemeth