我正在将 Rails 应用程序移植到 Rails 4.2。这个 Rails 应用程序在关联中包含一些相当复杂的手动 SQL 代码 - 部分是由于数据库优化(例如子选择而不是 JOIN),部分是由于在撰写本文时没有可行的替代方案(Rails 3.0),部分肯定是由于缺乏知识(我希望,至少 - 这很容易解决)。
示例:InternalMessage 类。消息可以在用户之间发送(InternalMessage 的收件人和消息的“删除”存储在InternalMessagesRecipients 中,因为可以有多个),并且可以读取、回复、转发和删除消息。该协会看起来像这样:
class User < AR::Base
has_many :internal_messages,
:finder_sql => "SELECT DISTINCT(internal_messages.id), internal_messages.* FROM internal_messages " +
' LEFT JOIN internal_messages_recipients ON internal_messages.id=internal_messages_recipients.internal_message_id' +
' WHERE internal_messages.sender_id = #{id} OR internal_messages_recipients.recipient_id = #{id}',
:counter_sql => 'SELECT count(DISTINCT(internal_messages.id)) FROM internal_messages ' +
' LEFT JOIN internal_messages_recipients ON internal_messages.id=internal_messages_recipients.internal_message_id' +
' WHERE internal_messages.sender_id = #{id} OR internal_messages_recipients.recipient_id = #{id}'
# ...
end
关键部分是末尾的“OR”子句 - 通过这种关联,我想同时获取接收和发送的消息,这些消息分别与用户表连接:
has_many :sent_messages, -> { where(:sender_deleted_at => nil) }, :class_name => 'InternalMessage', :foreign_key => 'sender_id' #, :include => :sender
has_many :internal_messages_recipients, :foreign_key => 'recipient_id'
has_many :rcvd_messages, :through => :internal_messages_recipients, :source => :internal_message, :class_name => 'InternalMessage'
因为InternalMessage可能有多个收件人(也可以发送给发件人本人)。
问:如何移植这个finder_sql
兼容 Rails 4.2has_many
定义?