Логика текущих разговоров для простой системы обмена сообщениями - PullRequest
3 голосов
/ 05 сентября 2011

Я создаю простую систему обмена сообщениями с 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 Ответ

6 голосов
/ 05 сентября 2011

Необходимо рассмотреть два набора сообщений:

  • Те, где 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 отправил сообщения, и объединит их с пользователями, отправившими сообщения на the_user_in_question; В результате будут все пользователи, которые участвуют в беседах с the_user_in_question в виде массива пользовательских экземпляров. Поскольку в UNION есть IN, вы можете использовать UNION ALL, чтобы избежать дополнительной работы в UNION.

Возможно, вы захотите обернуть это в метод класса в сообщении:

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 и messages.to_id в вашей базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...