ledermann/unread

Is there a way to group records by unread?

firedev opened this issue · 7 comments

Hi,

Is there any way to put unread items on top?

@firedev : you can do with_read_marks_for(user).order('read_marks.timestamp DESC')

This didn't do anything, I will try a bit later again to see what SQL will be produced.

@LuckyThirteen: The above will not work, because after doing a cleanup with cleanup_read_marks!, old items don't have a read_mark. Instead, you have to check the global read_mark for the user, too.

I don't think there is an efficient way to build a list with unread items on top, sorry.

Is there ANY way to do it? Find items without readmarks?

I don't know why you closed this, but anyway here you go:

Inquiry.with_read_marks_for(current_user).order('IF(read_marks.readable_id IS NULL, 1, 0) DESC')

@firedev I ended up doing something like this in my model because I needed to order by updated_at as well:

  def self.inboxable_for(user)
    # Without accounting for the reader's global timestamp, recently read items get shoved
    # down to the bottom of the list
    global_timestamp = user.read_mark_global(self).try(:timestamp) || 30.years.ago

    with_read_marks_for(user)
      # ISNULL might be MySQL specific
      .select("ISNULL(read_marks.readable_id) AND updated_at > '#{global_timestamp.to_s(:db)}' AS unread")
      .order('unread DESC, updated_at DESC')
  end

For anyone coming here now. @jarinudom thanks for the hint. For me, this was enough:

class NotificationsIndexQuery

  def results(scope:, reader:)
    scope
      .with_read_marks_for(reader)
      .select('(read_marks.readable_id IS NULL) AS unread')
      .order('unread DESC, created_at DESC')
  end

end

# NotificationsIndexQuery.new.results(scope: Notification, reader: current_employee)