我正在使用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消息的内容,为每个对话显示一行。
任何想法都会非常有用。
谢谢! 丹尼
答案 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
添加索引。