用例
我有 3 个模型:
- 一个
Message
- 一个
Conversation
- 一个
MessageRecipient
关系定义为
- A
message
has_and_belongs_to_many
conversations
(反之) - 一个
message
has_many
message_recipients
- A
MessageRecipient
belongs_to
amessage
和 arecipient
(此处未定义)
它的工作原理
方法
@recipient.inbox_conversations.first.messages
创建以下 SQL 查询:
SELECT *
FROM `messages`
INNER JOIN `conversations_messages`
ON `messages`.id = `conversations_messages`.message_id
WHERE (`conversations_messages`.conversation_id = 2061 )
结果是预期的消息:
[#<Message id: 7045, ..>]
问题
下一个方法(与上一个方法相同,具有额外的命名范围)
@recipient.inbox_conversations.first.messages.received_by(@recipient)
创建以下 SQL 查询:
SELECT * FROM `messages`
INNER JOIN `message_recipients`
ON `message_recipients`.message_id = `messages`.id
INNER JOIN `conversations_messages`
ON `conversations_messages`.message_id = `messages`.id
WHERE (`conversations_messages`.conversation_id = 2060 )
AND (`message_recipients`.recipient_id = 32363)
它返回了一个不存在的ActiveRecord 元素
[#<Message id: 9025, ..>]
我试图Message.find_by_id(9025)
在这一行之后做一个,这会返回nil
。
你想要一些额外的代码吗?
class Message
named_scope :received_by, lambda { |recipient| {
:conditions => [ "`#{MessageRecipient.table_name}`.recipient_id = ?", recipient.id ],
:joins => "INNER JOIN `#{MessageRecipient.table_name}`
ON `#{MessageRecipient.table_name}`.message_id = `#{Message.table_name}`.id"
} }
.
class Receiver
def inbox_conversations
inbox_messages = Message.received_by(self).find(:all, :include => :conversations)
return inbox_messages.map(&:conversations).flatten.uniq
end
感谢您阅读本文!