Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I am working on a Rails 3.2.6 app for a friend which has implements some message board functionality. Users can post messages into a categories. Each user also has a list of other users they have friended.

I got a feature request recently to display the number of unread posts made by the current user's friends next to each category. This is tracked on a category basis, not a per post basis, since the posts are displayed on a main newsfeed and you can't read a single post. So the feature request states that when a user clicks a category, which filters posts by that category, it will reset the unread count for that category.

I've implemented the unread counter by adding a database table that tracks the last time a user "read" all the messages. The table contains user_id, category_id, and last_read_time.

Now I am trying to implement the unread counters. I set up some scopes in my Post model (some of these are used in different places, which is why they are separate scopes):

scope :by_users, lambda { |users| where("user_id IN (?)", users) unless users.nil? }
scope :by_categories, lambda { |categories| where("category_id IN (?)", categories) unless categories.nil? }
scope :since, lambda { |date| where("updated_at > ?", date) unless date.nil? }

Here is my first crack at an unread method (also in the Post model):

def self.unread_count(user, category)
  read_time = ReadStatus.where("user_id = ? AND category_id = ?", user.id, category.id).first

  if read_time.nil?
    #handle it
  end

  #if user has no friends, there will be no unread posts displayed
  if user.friends.count == 0
    return
  else
    friends = user.friends
  end

  unread = by_users(friends).since(read_time.last_read_time).by_categories(category.id).count

  unless unread == 0
    "(" + unread.to_s + " new)"
  end
end

This works fine, but I would like to make this more efficient. Right now, there are 81 categories users can post in. This means when the homepage loads there are 81 count queries firing off, and this is repeated anytime the homepage is re-loaded. I can't think of any way to cache this value or eliminate these queries, since the unread count can change at any given moment and needs to be refreshed when the page is reloaded.

Any tips/tricks/Rails pixie dust to make this better? Every solution I think of either results in stale counter values or a large DB hit (for what I feel is a fairly trivial "feature")

share|improve this question

migrated from stackoverflow.com Sep 23 '12 at 0:31

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.