I have a simple rails 3 blog app where posts have many comments and comments belong to a post.
I want to create a scope that will fetch all posts that have more than 5 comments.
What's the best way of doing this without a counter cache column.
Like this, perhaps?
Post.select('posts.*, count(comments.id) as comment_count').
joins(:comments).
group('posts.id').
having('comment_count > 5')
In Postgres 9.1 I had to set things up like this as postgres isn't happy putting conditions on calculated fields or something like that.
Post.select('posts.*, count(comments.id) as comment_count').
joins(:comments).
group('posts.id').
having('count(comments.id) > 5')
Great answer from noodl... thanks for that!
I needed to find - to stick with the example classes of the original question - the 4 posts that were most recently commented on... a slight variant of noodl's answer does the trick:
Post.select('posts.*, max(comments.created_at) as last_commented_at').
joins(:comments).
group('posts.id').
order('last_commented_at DESC').
limit(4)
Thanks!
Related
I'm having trouble sorting my table based on the votes column, votes is a multivalued attribute so I use count and try to sort it based on that. here is the code
#topics = Topic.find(:all,:order=>'#topic.votes.count DESC')
Rails returns an error that says
ActiveRecord::RecordNotFound in TopicsController#index
Couldn't find all Topics with 'id': (all, {:order=>"#topic.votes.count DESC"}) (found 0 results, but was looking for 2)
Just starting out with rails and still confused with some things, your help will be much appreciated.
this is Rails 2 syntax being used in higher Rails version.
You can do something like this:
Topic.joins(:votes).group('topics.id').order('count(topics.id) DESC')
Instead of join include is best and faster option
Topic.include(:votes).group('topics.id').order('count(topics.id) DESC')
Thanks to ahmed and snehal, I was able to find out the answer I'm looking for, which is
Topic.left_outer_joins(:votes).group('topics.id').order('count(topics.id) DESC')
If I had an ActiveRecord model, Foo, which had two date columns, date_1 and date_2, and I wanted to sort by the later of the two columns (the date that was later), how would this be done? Answers will be judged based on simplicity of the code and the least sql used.
similar question
Ruby or Rails sort on two/multiple date fields
I'm leaning towards the following but I don't know if there is a better way.
Tested code:
Foo.select("CASE
WHEN date_1 > date_2 THEN date_1
ELSE date_2
END AS later_date, *").order("later_date desc")
Try using this:
Foo.order('GREATEST(date_1, date_2) DESC')
What is want to do is exactly this:
mysql SQL: specific item to be first and then to sort the rest of the items
but for ActiveRecord.
Going by the solution for mySql provided in above question, i tried:
.order('user_id = 9 DESC')
but it didn't worked. Please help
2 models
Books (has_many: chapters)
Chapters (belongs_to: books)
Id like to display a list of books, but only books with chapters.
Here's what I have so far:
#books = Book.find(:all,:include => :chapters)
Problem here is that books is returning books w/o chapters (0 chapters)
when dealing with nested resources like this, how do I say find where count > 0 for chapters?
Right now I'm doing this in the controller, not sure if that's a problem. but i should probably move this to a model?
cheers
Add this code to Book:
scope :only_with_chapters, includes(:chapters).having('COUNT(chapters.id) > 0').group('books.id')
And to use it just run Book.only_with_chapters
Depends on performance use joins, instead of includes.
Using joins it will look like:
scope :only_with_chapters, includes(:joins).group('books.id')
I'm having trouble crafting a fairly simple query with Doctrine...
I have two arrays ($countries, $cities) and I need to check whether database record values would match any inside either. I'm looking for something like:
->whereIn('country', 'city', $countries, $cities)
... with 'country' being a WHERE IN for $countries and 'city' being a WHERE IN for $city.
I could separate the two out but the needed query has lots of other conditions so that's not possible. The resulting SQL I'm after would be:
SELECT ...
WHERE ...
AND ...
AND ...
AND ('country' IN (1,2,3) OR 'city' IN (7,8,9))
AND ...
AND ...;
One could therefore think of it also as a bracketing issue only. Anyone know if this is possible with Doctrine DQL? I've looked through the documentation but can't find any direction.
Thanks
After an hour of experimenting on this nonsense, here's the syntax to make it work.
$q->andWhere('country IN ? OR city IN ?', array(array(1, 2, 3), array(7, 8, 9)));
Why not use something like?
$countryIds=[1,2,3];
$cityIds=[7,8,9];
$q->whereIn('country',$countryIds)->andWhereIn('city',$cityIds);
Also, chain them together for context (most Doctrine methods return $this).
see http://www.symfony-project.org/doctrine/1_2/en/06-Working-With-Data