I have post and comments tables where of course comments belongs to posts.
I want to sort posts now with eloquent by amount of comments.
How can i do that in laravel?
I tried to order by date using:
Post::orderBy('created_at', 'DESC')->paginate(6);
i want the same but sorting by comments with are on other database but they are connected in model.
EDIT:
I end up now having this query:
$post = Post::
join('comments', 'comments.post_id' , '=', 'posts.id')
->groupBy('posts.id')
->orderBy(DB::raw('COUNT(posts.id)'))
->paginate(6);
{{ $post->author }} works...
but i cant get for example {{ $post->comment->count()}} from blade. In my previous query (above) it works. dunno why.
This answer makes help.
You should be able to use the Collection's sortBy() and count() methods to do this fairly easily.
$hackathons = Hackathon::with('participants')->get()->sortBy(function($hackathon)
{
return $hackathon->participants->count();
});
Related
Let's take the example from the doc : https://laravel.com/docs/5.7/eloquent-relationships#many-to-many-polymorphic-relations it's easy to get all posts with their tags count doing Post::withCount('tags')->get().
But how to get all tags with their usage count ? To have them ordered by most used / less used.
If I do Tag::withCount(['video', 'post'])->get() I will have 2 attributes videos_count and posts_count. In my case I would like a unique taggables_count that will be the sum of the two. In a perfect world by adding a subselect querying the pivot table.
I would suggest simply doing the call you already did, which is Tag::withCount(['video', 'post'])->get(), and add this to your Tag model:
// Tag.php
class Tag
{
...
// Create an attribute that can be called using 'taggables_count'
public function getTaggablesCountAttribute()
{
return $this->videos_count + $this->posts_count;
}
...
}
and then in your loop (or however you use the items in the collection):
#foreach($tags as $tag)
{{ $tag->taggables_count }}
#endforeach
This setup requires you to get the Tags with the withCount['video', 'post'] though. If you do not, you will likely get 0in return for $tag->taggables_count.
If you're really concerned about speed, you would have to create the query manually and do the addition in there.
So after more searching I find out there is no way to do it with only in one query due to the fact that in mysql we can't do a select on subselet results. So doing Tag::withCount(['videos', 'posts']) and trying to sum in the query the videos_count and posts_count will not work. My best approach was to create a scope that read results in the pivot table :
public function scopeWithTaggablesCount($query) {
if (is_null($query->getQuery()->columns)) {
$query->select($query->getQuery()->from . '.*');
}
$query->selectSub(function ($query) {
$query->selectRaw('count(*)')
->from('taggables')
->whereColumn('taggables.tag_id', 'tags.id');
}, 'taggables_count');
return $query;
}
To use it :
$tags = Tag::withTaggablesCount()->orderBy('name', 'ASC')->get();
So now we have a taggables_count for each tag and it can be used to order by. Hope it can help others.
This question already has answers here:
Laravel eloquent counting a relation
(3 answers)
Closed 5 years ago.
I am trying to make a query where I get the number of comments on a News in a row in laravel.
News Table
News_Comments Table
Display count of comments in 'Kommentare'
This is the query in mysql.
SELECT news.Id,news.title,news.body,news.created_at, COUNT(news_comments.id) AS Kommentare
FROM news
LEFT JOIN news_comments ON news_comments.fk_news_id = news.id
GROUP BY news.id
Result of this query
How would I write that in laravel 5.5?
Thank you very much!
You have to set the relationship between News and NewsComments.
In News Model, supposing that news_comments is in NewsComment Model, in App folder. Set the relationship:
public function newsComments()
{
return $this->hasMany('App\NewsComment', 'fk_news_id');
}
And then, to get the count, you can use count() method:
$count = $news->newsComments()->count();
Or, directly using blade:
{{ $news->newsComments()->count() }}
Make a model for news table name News and another for comments table name Comment. And then in your News model, define a hasMany() relationship method like -
public function comments(){
return $this->hasMany(Comment::class);
}
And then in your controller, retrieve like this-
$newses = News::with('comments')->get();
This will load all news with corresponding all comments. If you want to load single news with all comments then -
$news = News::with('comments')->where('id',$news_id)->first();
To get the comment count, you can count() on relationship like -
$count = News::find($news_id)->comments()->count();
I have a problem and can't figure out how to solve it. I've searched online but still couldn't get a firm answer. What I'm trying to do is to paginate Inquiries table - or the query below. Everything seems to work (at least I'm getting 20 inquiries per page, however I can't figure out how to display the links()?
I'm saving Inquiries in the $thecusts collection and passing it to the view.
Tables and relations : Employees - Dealers (manytomany)
Dealers-customers(1 to many)
Customers-inquiries (1 to many).
So I need to paginate x Inquiries for the employee that has many dealers.
Anyone can help ?
$justch = $me->employeehasdealers()->get(['dealers.dealer_id','dealer','abbreviation']); //list of dealers assigned to auth employee
$justch2=$justch->load(['DealerHasInquiries'=>function($query){
$query->with('inquiriescomments:comments_inquiries_id,inquiry_id,employee_id,comments','inquiryspdl','inquiriescustomers:customer_id,customer')->paginate(20);
}]);
$thecusts = new Collection();
foreach ($justch2 as $just) {
$thecusts = $thecusts->merge($just->DealerHasInquiries);
}
The problem is you're not passing back the paginator instance. You can manually create one in your controller based on $thecusts:
$perPage=20;
return view('my-view', ['paginator' => new Paginator($thecusts->toArray(), $perPage)]);
Then you can call the links method on the paginator instance in your view:
{{ $paginator->links() }}
Edit
You may be able to simply all this though in a single query like:
$thecusts = $me->employeehasdealers()->with(['DealerHasInquiries'=>function($query){
$query->with('inquiriescomments:comments_inquiries_id,inquiry_id,employee_id,comments','inquiryspdl','inquiriescustomers:customer_id,customer');
}])->paginate(20);
return view('my-view, compact('thecusts'));
however I can't figure out how to display the links()?
You can do this in your blade:
{{ $justch2->links() }}
The Answer has been posted by btl - (Much appreciate it!)
Here is my code with some additions:
Controller:
$perpage=19;
$justch = $me->employeehasdealers()->with(['DealerHasInquiries'=>function($query) use ($perpage){
$query->with('inquiriescomments:comments_inquiries_id,inquiry_id,employee_id,comments','inquiryspdl','inquiriescustomers:customer_id,customer')->simplePaginate($perpage);
}])->get(['dealers.dealer_id','dealer','abbreviation']);
foreach ($justch as $just) {
$thecusts = $thecusts->merge($just->DealerHasInquiries);
}
$paginator = new Paginator($thecusts->toArray(),$perpage, Paginator::resolveCurrentPage(),['path'=>Paginator::resolveCurrentPath()]);
$inquiries = $thecusts;
return view('/inquiries', ['paginator'=>$paginator,'inquiries' => $inquiries]);
Blade: {{$paginator->links()}}
I there, im using eloquent to create a query where gets the galleries from a specific user_id, but i want also to implement the pagination, but is not working the way im doing.
ex:
$galleries = Gallery::paginate(10)->where('user_id', $userId)
->get();
$galleries = Gallery::where('user_id', $userId)->paginate(10);
In the controller you are supposed to do :
$galleries = Gallery::where('user_id', $userId)->paginate(10);
In the view use :
{{ $galleries->appends(Input::except('page'))->links() }}
I have post table and comments table. I want to get all posts with its comments and the following returns just post which has comments:
Post::with('comments')
UPDATE
for example
post_table
id post
1 post1
2 post2
comment table
id post_id comment
1 1 sapmle_comment
Post::with('comments') returns only that posts, which have comments, it returns only first post, becouse second post doesnot have comments, i want to get all post (with or without comments)
Your question is not clear enough but to get all the posts with comments you may try this:
$posts = Post::with('comments')->get();
To get posts only which has comments you may try this:
$posts = Post::has('comments')->get();
I'm not too sure what your question is, but I am assuming that it is not returning your comments. If your not able to return posts that do not have comments Sheikh's answer will work for you. If you are not able to retrieve the comments for each post you should make sure your model has defined:
public function comments(){
return $this->hasMany('Comment');
}
and then make sure your comments model has:
public function post(){
return $this->belongsTo('Post');
}
If you want to pass this along to your view from the controller you can:
$comments = $post->comments()->orderBy('created_at')->get();
return View::make('view', compact('comments'));
You can loop through each of the comments by:
#foreach ($comments as $comment)
{{$commment->content}}
#endforeach