简单消息传递系统的当前对话逻辑

时间:2011-09-05 17:55:57

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord

我正在使用Rails3构建一个简单的消息传递系统,允许用户相互发送私人消息。每组用户可以在彼此之间拥有单个消息流(如短信)

然而,我对用于构建视图的逻辑感到困惑,该视图显示了用户正在进行的所有当前对话。这包括可能仅包含自己发送的消息的对话。

我的架构有以下内容:

  create_table "messages", :force => true do |t|
    t.integer  "from_id"
    t.integer  "to_id"
    t.string   "message"
    t.datetime "created_at"
    t.datetime "updated_at"
  end 

我想模仿类似于FB消息的内容,为每个对话显示一行。

任何想法都会非常有用。

谢谢! 丹尼

1 个答案:

答案 0 :(得分:6)

需要考虑两组消息:

  • from_id是当前用户的那些。
  • to_id是当前用户的那些。

我选择find_by_sql并让数据库完成所有工作:

chatting_with = User.find_by_sql(%Q{
    select * from users where id in (
        select to_id   as user_id from messages where from_id = :the_user
        union all
        select from_id as user_id from messages where to_id   = :the_user
    )
}, :the_user => the_user_in_question.id)

SQL UNION只是对两个结果集进行了按顺序联合,因此上面将抓取the_user_in_question已向其发送消息的所有用户,并将其与已向{{1}发送消息的用户合并}};结果将是与the_user_in_question作为用户实例数组进行对话的所有用户。由于UNION上有the_user_in_question,您可以使用UNION ALL来避免在UNION中进行一些额外的工作。

您可能希望将它包装在Message:

上的类方法中
IN

然后你可以这样说:

def self.conversations_involving(user)
    User.find_by_sql(%Q{
        select * from users where id in (
            select to_id   as user_id from messages where from_id = :the_user
            union all
            select from_id as user_id from messages where to_id   = :the_user
        )
    }, :the_user => user.id)
end

在您的控制器中。

您还希望在数据库中向@other_users = Message.conversations_involving(current_user) messages.from_id添加索引。