我有对话模型
recipient_id
sender_id
获取当前用户的对话看起来像
conversations = Conversation.where("conversations.sender_id =? OR conversations.recipient_id =?",current_user.id,current_user.id)
让我们在会话中呼叫 other_user 非当前用户。
由于当前用户可以是发件人或收件人,因此无法在users表上使用JOIN或Include来获取对话中涉及的“其他用户”。因此,呈现对话会创建N + 1情况,为每个其他用户发出1个查询。
有没有办法使用includes或JOIN获取other_user,条件基本上是:
if current_user_id == recipient_id JOIN on recipient_id
if current_user_id == sender_id JOIN on sender_id
答案 0 :(得分:1)
如果你只需要other_user的某些属性,比如用户名,那么这样的东西应该有效:
conversations = Conversation.find_by_sql([<<-SQL, current_user.id, current_user.id, current_user.id])
SELECT
convos_involving_user.*
FROM
-- We'll use UNION to create a table that joins together the users and
-- conversations tables based on both sender and recipient. Each
-- conversation will be represented by two rows in this joined table:
-- one row joining that conversation to the sender's user info, another
-- row joining that conversation to the recipient's user info.
(
-- join conversations and users based on sender
SELECT
conversations.*, users.id AS user_id, users.username AS other_user
FROM
conversations
INNER JOIN
users ON users.id = conversations.sender_id
UNION
-- join conversations and users based on recipient
SELECT
conversations.*, users.id AS user_id, users.username AS other_user
FROM
conversations
INNER JOIN
users ON users.id = conversations.recipient_id
) AS convos_involving_user
-- Now that we conceptually have that big join table with two rows for
-- each conversation, we filter that table. First, we are only interested
-- in the conversations where either the recipient or sender is the
-- current user. But we still have duplicate rows for each message, so we
-- also filter out the rows that join a conversation rows to the
-- current_user's row. This leaves, for each conversation involving the
-- current user, the row that links the conversation to the other user.
WHERE
(recipient_id = ? OR sender_id = ?) AND user_id != ?
SQL
然后每个conversations
都会有一个other_user
方法,您可以在其上调用以获取其他用户的用户名。您可以在视图中使用它或诸如此类的东西。使用other_user
方法进行说明:
conversations.each { |convo| puts convo.other_user }
希望这有帮助。