I am creating a simple chatting app on rails 4. The controllers, models and views are created but the functionality is still incomplete. I have 2 tables in my database, conversations and messages. The conversation table holds two fields, sender id and receiver id. And the messages table holds 3 fields, body, user id and read(defaults to 0 meaning not read).
Models:
class Conversation < ActiveRecord::Base
belongs_to :sender, :foreign_key => :sender_id, :class_name => "User"
belongs_to :reciever, :foreign_key => :reciever_id, :class_name => "User"
has_many :messages, :dependent => :destroy
validates_uniqueness_of :sender_id, :scope => :reciever_id
scope :involving, lambda { |user_id|
where("sender_id = ? OR reciever_id = ?", user_id, user_id)
}
scope :between, lambda { |sender_id, reciever_id|
where("(sender_id = ? AND reciever_id = ?) OR (sender_id = ? AND reciever_id = ?)", sender_id, reciever_id, reciever_id, sender_id)
}
def other_interlocutor(user_id)
if sender.id == user_id
return reciever.id
else
return sender.id
end
end
end
class Message < ActiveRecord::Base
belongs_to :conversation
belongs_to :user
validates_presence_of :conversation_id, :user_id, :body
end
What I am trying to do is to create a real-time functionality of receiving unread messages count whenever someone receives a new message. I am using private pub to create the chat between users.
I have a user model which contains this function:
def unread_messages_count
unread_messages = 0
# puts "Putting self conversations ! #{self.conversations.first}"
conversations = Conversation.involving(self.id)
conversations.each do |conversation|
unread_messages += conversation.messages.where(:read => 0, :user_id => conversation.other_interlocutor(self.id)).count
end
return unread_messages = unread_messages == 0 ? nil : unread_messages
end
I have one page where all user's conversations are listed and one a conversation is clicked all the messages related to that conversation are listed too. On the same page I have subscribed every conversation_messages_path
to create separate channels for every conversation. Whenever a message is sent a create.js.erb
file is rendered where I publish to those subscribed channels:
<% publish_to conversation_messages_path(@conversation.id) do %>
$("#conversations_link").text("<%= current_user.unread_messages_count %> Conversations");
$("#messages").append("<%= escape_javascript render(:partial => 'message', :locals => { :message => @message })%>");
<% end %>
The $("#conversation_link")
is where I want to show the unread messages count.
Currently, the unread messages count is returning back the wrong count and the navbar is only updated when the conversation.sender_id
messages the receiver.
My unread message counter is not returning the correct number of unread messages. I don't know how to fix it. What's wrong in my code? Thanks.