14

I am using mailboxer gem with my rails application, and i want to order my inbox messages so that when the user receives a new message, I would like to have a notification or keep track of which messages have been read and which have not and order the messages to have the unread / new messages at the top of the page.

Here is my conversations controller

class ConversationsController < ApplicationController
  before_action :get_mailbox
  before_action :get_conversation, except: [:index]

  def index
    @unread_messages = @mailbox.inbox(unread: true).count
    @conversations = @mailbox.inbox({page: params[:page], per_page: 10})
  end

  private

  def get_conversation
    @conversation ||= @mailbox.conversations.find(params[:id])
  end

  def get_mailbox
    @mailbox ||= current_user.mailbox
  end
end

i tried to order the mail by:

@conversations = @mailbox.inbox({page: params[:page], per_page: 10}).joins(:receipts).select("mailboxer_conversations.*, mailboxer_receipts.*").order('mailboxer_receipts.is_read')

but it did not worked.

Please suggest a solution.

Sachin Singh
  • 7,107
  • 6
  • 40
  • 80

5 Answers5

1

try this,

def index
  @unread_messages = @mailbox.inbox(is_read:false).count
  @conversations = @mailbox.inbox.page(params[:page]).per(10)
end

and by default the inbox is ordered to show the newest message on the top, for example when you type @mailbox.inbox.first you are actually pulling the last (newest) message.

0

Okay - so looking through the docs here is what I've got.

Has #is_read worked for you elsewhere? The methods and attributes I could track down are #mark_as_read and receipt.is_unread?; have you tried organizeing by is_unread instead or tried a little debugging of this in the console?

Here are the resources I was digging through:

  1. http://www.rubydoc.info/gems/mailboxer/frames

  2. cannot figure out how to update mailboxer is_read

Community
  • 1
  • 1
Nick Schwaderer
  • 1,030
  • 1
  • 8
  • 21
0

I don't know this Gem. There are my 2 cents anyway...

In order to paginate your messages, Mailboxer has to specify an SQL order internally. To know which order it is, check your Rails logs. I suppose you'll get something like ORDER BY created_at DESC, mailboxer_receipts.is_read (I have added your order).

To change this priority, you'll have to unorder your query and place your is_read criteria first. You'll be able to do this with something like:

@conversations =
  @mailbox
    .inbox(
      page: params[:page],
      per_page: 10
    ).joins(:receipts)
    .select("mailboxer_conversations.*, mailboxer_receipts.*")
    .reorder('mailboxer_receipts.is_read, WHATEVER_YOU HAD IN YOUR SQL query')

Hope this helps... Have a nice day anyway :)

edit :

By looking in the Mailboxer Gem, I confirm there is an internal order (https://github.com/mailboxer/mailboxer/blob/51fd6391592aace8a8eb3d1b1a761a9bea81fe1b/app/models/mailboxer/conversation.rb): see the participant and inbox scopes.

scope :participant, lambda {|participant|
  where('mailboxer_notifications.type'=> Mailboxer::Message.name).
  order("mailboxer_conversations.updated_at DESC").
  joins(:receipts).merge(Mailboxer::Receipt.recipient(participant)).uniq
}
scope :inbox, lambda {|participant|
  participant(participant).merge(Mailboxer::Receipt.inbox.not_trash.not_deleted)
}

Also, you'll just have to write your order before the inbox call and it should work as you want:

@conversations =
  @mailbox
    .order('mailboxer_receipts.is_read')
    .inbox(
      page: params[:page],
      per_page: 10
    ).joins(:receipts)
    .select("mailboxer_conversations.*, mailboxer_receipts.*")
romainsalles
  • 2,051
  • 14
  • 17
0

You can check gather all the unread messages by doing the following:

 @unread = @conversations.select{ |c| c.is_unread?(current_user) }

This will go through all of the conversations and return an array of only the unread messages. Are you saying that you want the inbox to have the unread first, even if there are newer messages that are already read?

Sara Fuerst
  • 5,688
  • 8
  • 43
  • 86
-1

I believe that what you're looking for is the following:


@conversations = @mailbox.inbox.select('mailboxer_conversations.*, bool_and(is_read) AS all_read').group('mailboxer_conversations.id').order('all_read ASC')

Roman
  • 13,100
  • 2
  • 47
  • 63