Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessing read/unread stats via another relationship #77

Closed
brendon opened this issue Jul 31, 2016 · 7 comments
Closed

Accessing read/unread stats via another relationship #77

brendon opened this issue Jul 31, 2016 · 7 comments

Comments

@brendon
Copy link

brendon commented Jul 31, 2016

Hi there, I've spent a bit of time trying to figure this out so I thought I'd ask here in case you had any pointers :)

I have a model called Values. A value has many comments, and the comments readable via your gem.

I'm rendering a document full of values so I want to select all the values in a document, and also have an additional two columns: comments_count and unread_comments_count. This allows me to render the document indicating the comments as efficiently as possible. Right now I'm issuing a query for each unread_by call that is causing a performance problem.

I've had some success getting an unread_count by merging unread_by() into the query and forcing a LEFT JOIN between values and comments. But then it doesn't seem possible to get a count of all of the comments (read and unread) in that same query.

Any pointers would be greatly appreciated. :)

@brendon
Copy link
Author

brendon commented Jul 31, 2016

I ended up not eager loading the comments at all (as I don't actually use the objects). Instead I'm generating a statistics hash like this:

default_hash = Hash.new { |h, k| h[k] = { unread: 0, total: 0 } }
document.comments.with_read_marks_for(current_user).reduce(default_hash) do |hash, comment|
  hash[comment.value_id][:unread] += 1 if comment.unread?(current_user)
  hash[comment.value_id][:total] += 1
  hash
end

Results in one query at the start plus several (ultimately cached) queries on the read_marks table when there are no read_marks. Works pretty well.

@ledermann
Copy link
Owner

Using with_read_marks_for is the key. It uses just one query and make sure that the following unread? invocations use the result of the first query (see code).

Your solution looks fine.

@brendon
Copy link
Author

brendon commented Aug 1, 2016

Thanks @ledermann, yep it's working great. Thanks for the help :)

@Frexuz
Copy link
Contributor

Frexuz commented Mar 17, 2018

Just stumbled upon this. @brendon's solution was exactly what we were looking for.

It would be a great addition to the README (the whole example?), and explaining that subsequent unread?(user) doesn't do an additional query. 👍

A bit unnecessary to dig through the issues / finding it by chance :)

@brendon
Copy link
Author

brendon commented Mar 17, 2018

Glad I was able to be of some help @Frexuz :) I'm sure @ledermann would appreciate a PR with the documentation enhancements if you had the time to do it. Would you be keen? :)

@Frexuz
Copy link
Contributor

Frexuz commented Mar 17, 2018

Let me give it a go :) Then @ledermann can adjust

@Frexuz
Copy link
Contributor

Frexuz commented Mar 17, 2018

PR here #98

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants