首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails,SQL:私人聊天,如何在每次对话中找到最后一条消息

Rails,SQL:私人聊天,如何在每次对话中找到最后一条消息
EN

Stack Overflow用户
提问于 2013-11-19 13:10:10
回答 2查看 761关注 0票数 1

我得到了折叠式

代码语言:javascript
复制
+----+------+------+-----------+---------------------+--------+
| id | from | to   | message   | timestamp           | readed |
+----+------+------+-----------+---------------------+--------+
| 46 |    2 |    6 | 123       | 2013-11-19 19:12:19 |      0 |
| 44 |    2 |    3 | 123       | 2013-11-19 19:12:12 |      0 |
| 43 |    2 |    1 | ????????? | 2013-11-19 18:37:11 |      0 |
| 42 |    1 |    2 | adf       | 2013-11-19 18:37:05 |      0 |
+----+------+------+-----------+---------------------+--------+

from/to是用户的ID,message -显然是消息、时间戳和读标志。当用户打开他的配置文件时,我希望他看到他参与的对话框列表,最后一条消息显示在这个对话框中。为了在我编写这段代码的两个人之间找到一个对话,它很简单(消息模型):

代码语言:javascript
复制
def self.conversation(from, to)
  where(from: [from, to], to: [from, to])
end

所以,我现在可以对信息进行排序,并得到最后一个消息。但是,对每个对话框进行大量查询并不是很酷。怎样才能以更少的查询达到我想要的结果呢?

更新

好吧,看上去还不太清楚,我想要达到什么目的。例如,有4个用户-- Kitty、Dandy、Beggy和Brucy --使用了该聊天。当布吕西进入对话时,她会看到

代码语言:javascript
复制
Beggy: hello brucy haw ar u! | <--- the last message from beggy
------- 
Dandy: Hi brucy! | <---- the last message from dandy
--------
Kitty: Hi Kitty, my name is Brucy! | <–– this last message is from current user

所以,三个分开的对话。然后,布鲁西可以进入任何人的对话继续私人对话。我不知道如何在不为用户之间的每个对话触发一个查询的情况下获取这些记录。

EN

回答 2

Stack Overflow用户

发布于 2015-11-24 22:48:17

这个答案有点晚,但至少在Rails 3.2.x中,似乎没有一个很好的方法来做到这一点。

然而,这是我想出的解决方案(因为我在我的网站上也遇到了同样的问题)。

代码语言:javascript
复制
  @sender_ids =
    Message.where(recipient_id: current_user.id)
           .order("created_at DESC")
           .select("DISTINCT owner_id")
           .paginate(per_page: 10, page: params[:page])
  sql_queries =
    @sender_ids.map do |user|
      user_id = user.owner_id
      "(SELECT * FROM messages WHERE owner_id = #{user_id} "\
      "AND recipient_id = #{current_user.id} ORDER BY id DESC "\
      "LIMIT 1)"
    end.join(" UNION ALL ")

  @messages = Message.find_by_sql(sql_queries)
  ActiveRecord::Associations::Preloader.new(@messages, :owner).run

这是你发送信息给的最后10个独特的人。对于这些人中的每一个,它创建一个UNION查询,以获取发送给这10个唯一人员的最后一条消息。有50,000行,查询在大约20 50内完成。当然,要获得预加载的连接,您必须使用.includes在使用.find_by_sql时不能工作。

票数 0
EN

Stack Overflow用户

发布于 2013-11-19 13:53:58

代码语言:javascript
复制
def self.conversation(from, to)
  order("timestamp asc").last
end

编辑:

这条铁路会有帮助..。

http://railscasts.com/episodes/316-private-pub?view=asciicast

EDIT2:

代码语言:javascript
复制
def self.conversation(from, to)
    select(:from, :to, :message).where(from: [from, to], to: [from, to]).group(:from, :to, :country).order("timestamp DESC").limit(1)
end
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20072453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档