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

Dan*_*nny 3 ruby activerecord ruby-on-rails ruby-on-rails-3

我正在使用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 
Run Code Online (Sandbox Code Playgroud)

我想模仿类似于FB消息的东西,每个对话显示一行

任何想法都会非常有用.

谢谢!丹尼

mu *_*ort 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)
Run Code Online (Sandbox Code Playgroud)

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

您可能希望将它包装在Message上的类方法中:

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
Run Code Online (Sandbox Code Playgroud)

然后你可以说:

@other_users = Message.conversations_involving(current_user)
Run Code Online (Sandbox Code Playgroud)

在你的控制器中.

你会希望添加索引到messages.from_id,并messages.to_id在你的数据库了.