views:

37

answers:

2

I am building a group blog that is moderated by the community. When a user visits the moderate page, he is served up a random post that he has not yet moderated, and asked whether or not the post should appear.

So, the relevant objects are Post, User, and Moderation. A Moderation has a post_id and a user_id. I want to find a post from the set Post.all where there does not exist a Moderation object corresponding to that post and the current user.

What's the most efficient way of doing this? I could get all of the moderations for that user, and then use map to get all of the posts that the user moderated, and then query the posts database as (pseudocode) Post.find(:conditions => "id != [list of posts already moderated]) but I'm worried that might be slow? Is there a faster way?

Also, would it be a good idea to cache this somehow? Maybe by getting all posts that haven't been moderated, and saving that somewhere, and then when future calls to the moderate method are made, check that cache first and serve up a post (and remove that post from the cache), and only checking again for more posts if the cache is empty?

Thanks for your help!

+2  A: 

Just off top of my head:

Post.all(:joins => 'LEFT OUTER JOIN moderations m ON p.id=m.post_id AND m.user_id != #{id}')
Eimantas
Using `:joins` will make returned posts read only. Pass `:readonly => false` as well if it is not desired. See http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001777
skalee
Thanks. This is db-independent, right?
unsorted
I think it's any ANSI-SQL rdbms-compatible.
Eimantas
A: 

I'm new to Ruby and thought I'd have a go at writing a program to do this, the end result is pretty bad in my opinion, but I thought I'd post the relevant part here anyway:

posts - moderations.select{|x| x.user_id == current_user}.collect{|x| x.post_id}
Josh
Avoid loading all the records and selecting/mapping it in your application. All that should be done in database, which would return you only relevant records. See ActiveRecord docs how to do it.
skalee