I made a messaging system from scractch on my App. All works good but i just want to customize more. So I want to display the last message for each Conversation by user_id inbox in my view . I have 2 models : Conversation and Message.
I can display only this
I m lost. Can you help me ?
messages_controller.rb
class MessagesController < ApplicationController
before_action :authenticate_user!
before_action do
@conversation = Conversation.find(params[:conversation_id])
end
def index
@messages = @conversation.messages
if @messages.length > 10
@over_ten = true
@messages = @messages[-10..-1]
end
if params[:m]
@over_ten = false
@messages = @conversation.messages
end
if @messages.last
if @messages.last.user_id != current_user.id
@messages.last.read = true;
end
end
@message = @conversation.messages.new
end
private
def message_params
params.require(:message).permit(:body, :user_id)
end
end
Conversations_controller.rb
class ConversationsController < ApplicationController
before_action :authenticate_user!
# GET /conversations
# GET /conversations.json
def index
@users = User.all
@camping = Camping.all
# Restrict to conversations with at least one message and sort by last updated
@conversations = Conversation.joins(:messages).distinct
end
private
# Use callbacks to share common setup or constraints between actions.
def conversation_params
params.require(:conversation).permit(:sender_id, :recipient_id, :user_id)
end
end
conversation.rb
class Conversation < ActiveRecord::Base
belongs_to :sender, :foreign_key => :sender_id, class_name: 'User'
belongs_to :recipient, :foreign_key => :recipient_id, class_name: 'User'
belongs_to :user
has_many :users, through: :messages
has_many :messages, dependent: :destroy
validates_uniqueness_of :sender_id, :scope => :recipient_id
scope :between, -> (sender_id,recipient_id) do
where("(conversations.sender_id = ? AND conversations.recipient_id =?) OR (conversations.sender_id = ? AND conversations.recipient_id =?)", sender_id,recipient_id, recipient_id, sender_id)
end
end
message.rb
class Message < ActiveRecord::Base
belongs_to :conversation
belongs_to :user
validates_presence_of :body, :conversation_id, :user_id
/messages/index.html.erb
<% @messages.each do |message| %>
<% if message.body %>
<% user = User.find(message.user_id) %>
<%= image_tag user.avatar(:thumb), class:"imageavatarmessage" %></div>
<%= user.prenom %>
<%= message.message_time %>
<div class="list">
<%= message.body %>
<% end %>
<% end %>
<%= form_for [@conversation, @message], html: {class: "ui reply form"} do |f| %>
<%= f.text_area :body, class: "form-control" %>
</div>
<%= f.text_field :user_id, value: current_user.id, type: "hidden" %>
<%= f.submit "Add Reply", class: "ui blue labeled submit icon button" %>
<% end %>
Probleme is here, i just want to show last message for each conversation. /conversations/index.html.erb
<% @conversations.each do |conversation| %>
<% if conversation.sender_id == current_user.id || conversation.recipient_id == current_user.id %>
<% if conversation.sender_id == current_user.id %>
<% recipient = User.find(conversation.recipient_id) %>
<% else %>
<% recipient = User.find(conversation.sender_id) %>
<% end %>
<p>Conversation avec <%= link_to recipient.prenom, conversation_messages_path(conversation)%></p>
<p><%= image_tag recipient.avatar(:small), class:"imageavatarmessage" %></p>
<%= @conversations.last %>
<p>Il y a <%= time_ago_in_words(conversation.updated_at)%></p>
<% end %>
<% end %>
I want to display only the last one message for each conversations in my /conversations/index.html.erb I tested this <%= @conversations.last %> but it doesn't work...
Can you help me ?
My messages table
:body
:conversation, index: true
:user, index: true
:read, :default => false
t.timestamps
conversations table
:sender_id
:recipient_id
t.timestamps
end
end
end
After some test I can display last message. But this message is the same for all conversation... I can't have last message for each conversation. I don't know why...
Conversation_controller
@conversa = Conversation.where("? IN (recipient_id, sender_id)", current_user.id)
@test = Message.where(conversation_id: @conversa).group(:conversation_id).limit(1)
in my /conversations/index.html.erb
<% @test.each do |message| %>
<%= message.body %>
<%end%>
I think that, I m near the solution, can you help me please ?
If your current_user can directly reference the related conversations they are in you can setup your @conversations variable like this
def index
...
@conversations = current_user.conversations.joins(:messages)
end
Once that is setup you can iterate over it with each one in your index view
<% @conversations.each do |conversation| %>
<div>
Last Message for Conversation ID:<%= conversation.id %>
is <%= conversation.messages.last.body %>
</div>
<% end %>