从头开始在消息系统上显示最后一条正文消息
Display last body message on messaging system from scratch
我在我的应用程序上用 scratchch 制作了一个消息系统。一切正常,但我只想自定义更多。所以我想在我的视图中通过 user_id 收件箱显示每个对话的最后一条消息。我有 2 个模型:对话和消息。
我只能显示这个
我迷路了。你能帮帮我吗?
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 %>
问题来了,我只想显示每个对话的最后一条消息。
/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 %>
我只想显示我 /conversations/index 中每个对话的最后一条消息。html.erb 我测试了这个 <%= @conversations.last %> 但它不起作用...
你能帮帮我吗?
编辑
我的消息table
:body
:conversation, index: true
:user, index: true
:read, :default => false
t.timestamps
对话table
:sender_id
:recipient_id
t.timestamps
end
end
end
编辑 2
经过一些测试,我可以显示最后一条消息。但是这条消息对于所有对话都是一样的......我不能为每个对话都有最后一条消息。我不知道为什么...
Conversation_controller
@conversa = Conversation.where("? IN (recipient_id, sender_id)", current_user.id)
@test = Message.where(conversation_id: @conversa).group(:conversation_id).limit(1)
在我的 /conversations/index.html.erb
<% @test.each do |message| %>
<%= message.body %>
<%end%>
我想,我接近解决方案了,你能帮帮我吗?
使用 .count 代替 .length。
@messages = @conversation.messages
if @messages.count > 10
@over_ten = true
@messages = @messages[-10..-1]
end
或者您可以这样做:
def index
@messages = Messages.all.order("created_at DESC").limit(10)
end
如果您的 current_user 可以直接引用他们所在的相关对话,您可以像这样设置您的@conversations 变量
def index
...
@conversations = current_user.conversations.joins(:messages)
end
设置完成后,您可以在索引视图中对每个进行迭代
<% @conversations.each do |conversation| %>
<div>
Last Message for Conversation ID:<%= conversation.id %>
is <%= conversation.messages.last.body %>
</div>
<% end %>
任何想要包含最后一条消息的对话列表的人:
这是解决方案---我在 Rails 5.2.6 中完成并通过 API 我正在使用 Serializer 格式化 JSON 以获得更好的属性。
def conversations_list(user)
@user= User.find(@user_id)
ids = Message.select("MAX(id) AS id")
.group(:conversation_id).collect(&:id)
@result = Message.order("created_at DESC").where(:id => ids)
.joins(:conversation).order(id: :desc)
.where("sender_id = ? OR recipient_id = ?", user.id, user.id)
.paginate(page: params[:page],per_page:10)
if @conversations.present?
render json: {
success: true,
result: ActiveModel::Serializer::CollectionSerializer.new(@result, each_serializer: ConversationSerializer),
}
else
@conversations= []
render json: {
success: true,
result: ActiveModel::Serializer::CollectionSerializer.new(@conversations,
each_serializer: ConversationSerializer),
#micros: ActiveModel::Serializesr::CollectionSerializer.new(@micros,
each_serializer: MicroSerializer),
}
end
end
型号
# conversation.rb
has_many :messages
belongs_to :user
belongs_to :sender, :foreign_key => :sender_id, class_name: 'User'
belongs_to :recipient, :foreign_key => :recipient_id, class_name:
'User'
has_one :last_message, -> { order(created_at: :DESC) },class_name:
"Message"
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
belongs_to :conversation
belong_to :user
validates_presence_of :body, :conversation_id, :user_id
end
我在我的应用程序上用 scratchch 制作了一个消息系统。一切正常,但我只想自定义更多。所以我想在我的视图中通过 user_id 收件箱显示每个对话的最后一条消息。我有 2 个模型:对话和消息。
我只能显示这个
我迷路了。你能帮帮我吗?
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 %>
问题来了,我只想显示每个对话的最后一条消息。 /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 %>
我只想显示我 /conversations/index 中每个对话的最后一条消息。html.erb 我测试了这个 <%= @conversations.last %> 但它不起作用...
你能帮帮我吗?
编辑
我的消息table
:body
:conversation, index: true
:user, index: true
:read, :default => false
t.timestamps
对话table
:sender_id
:recipient_id
t.timestamps
end
end
end
编辑 2
经过一些测试,我可以显示最后一条消息。但是这条消息对于所有对话都是一样的......我不能为每个对话都有最后一条消息。我不知道为什么...
Conversation_controller
@conversa = Conversation.where("? IN (recipient_id, sender_id)", current_user.id)
@test = Message.where(conversation_id: @conversa).group(:conversation_id).limit(1)
在我的 /conversations/index.html.erb
<% @test.each do |message| %>
<%= message.body %>
<%end%>
我想,我接近解决方案了,你能帮帮我吗?
使用 .count 代替 .length。
@messages = @conversation.messages
if @messages.count > 10
@over_ten = true
@messages = @messages[-10..-1]
end
或者您可以这样做:
def index
@messages = Messages.all.order("created_at DESC").limit(10)
end
如果您的 current_user 可以直接引用他们所在的相关对话,您可以像这样设置您的@conversations 变量
def index
...
@conversations = current_user.conversations.joins(:messages)
end
设置完成后,您可以在索引视图中对每个进行迭代
<% @conversations.each do |conversation| %>
<div>
Last Message for Conversation ID:<%= conversation.id %>
is <%= conversation.messages.last.body %>
</div>
<% end %>
任何想要包含最后一条消息的对话列表的人: 这是解决方案---我在 Rails 5.2.6 中完成并通过 API 我正在使用 Serializer 格式化 JSON 以获得更好的属性。
def conversations_list(user)
@user= User.find(@user_id)
ids = Message.select("MAX(id) AS id")
.group(:conversation_id).collect(&:id)
@result = Message.order("created_at DESC").where(:id => ids)
.joins(:conversation).order(id: :desc)
.where("sender_id = ? OR recipient_id = ?", user.id, user.id)
.paginate(page: params[:page],per_page:10)
if @conversations.present?
render json: {
success: true,
result: ActiveModel::Serializer::CollectionSerializer.new(@result, each_serializer: ConversationSerializer),
}
else
@conversations= []
render json: {
success: true,
result: ActiveModel::Serializer::CollectionSerializer.new(@conversations,
each_serializer: ConversationSerializer),
#micros: ActiveModel::Serializesr::CollectionSerializer.new(@micros,
each_serializer: MicroSerializer),
}
end
end
型号
# conversation.rb
has_many :messages
belongs_to :user
belongs_to :sender, :foreign_key => :sender_id, class_name: 'User'
belongs_to :recipient, :foreign_key => :recipient_id, class_name:
'User'
has_one :last_message, -> { order(created_at: :DESC) },class_name:
"Message"
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
belongs_to :conversation
belong_to :user
validates_presence_of :body, :conversation_id, :user_id
end