Ruby on rails 移植到Rails>4.1有很多关系(没有finder\u sql)

Ruby on rails 移植到Rails>4.1有很多关系(没有finder\u sql),ruby-on-rails,activerecord,model-associations,finder-sql,Ruby On Rails,Activerecord,Model Associations,Finder Sql,我正在将Rails应用程序移植到Rails 4.2。这个Rails应用程序在关联中包含一些相当复杂的手动SQL代码——部分原因是DB优化,例如Subselect而不是Join,部分原因是在编写Rails 3.0时没有可行的替代方案,部分原因肯定是缺乏知识,至少我希望是这样——这很容易解决 示例:InternalMessage类。消息可以在用户和内部消息的接收者之间发送,消息的“删除”存储在InternalMessagesRecipients中,因为可以有多个,它们可以被读取、回复、转发和删除。该

我正在将Rails应用程序移植到Rails 4.2。这个Rails应用程序在关联中包含一些相当复杂的手动SQL代码——部分原因是DB优化,例如Subselect而不是Join,部分原因是在编写Rails 3.0时没有可行的替代方案,部分原因肯定是缺乏知识,至少我希望是这样——这很容易解决

示例:InternalMessage类。消息可以在用户和内部消息的接收者之间发送,消息的“删除”存储在InternalMessagesRecipients中,因为可以有多个,它们可以被读取、回复、转发和删除。该协会如下所示:

类用户从内部消息中选择distincentral\u messages.id、internal\u messages.*+ '在内部邮件上左加入内部邮件\u收件人。id=内部邮件\u收件人。内部邮件\u id'+ '其中internal_messages.sender_id={id}或internal_messages_recipients.recipient_id={id}', :counter_sql=>“从内部_消息中选择countdistincentral_messages.id”+ '在内部邮件上左加入内部邮件\u收件人。id=内部邮件\u收件人。内部邮件\u id'+ '其中internal_messages.sender_id={id}或internal_messages_recipients.recipient_id={id}' ... 终止 关键部分是末尾的OR子句-通过这种关联,我希望获得接收和发送的消息,它们分别与用户表连接:

有很多:已发送消息,->{where:sender\u deleted\u at=>nil},:class\u name=>'InternalMessage',:foreign\u key=>'sender\u id',:include=>:sender 有多个:内部\u邮件\u收件人,:外部\u密钥=>“收件人\u id” 有多条:rcvd\u消息,:至=>:internal\u消息\u收件人,:source=>:internal\u消息,:class\u name=>'InternalMessage' 因为内部消息可能有多个收件人,也可以发送给发件人本人


问:如何将此finder sql移植到Rails 4.2兼容的has多定义中?

将包含sql字符串的过程作为作用域传递

has_many :internal_messages, -> { proc { "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}' } }
更新

我不久前知道这毫无意义。has_-many关系必须至少在一个方向上具有内射连接,因此SQL子句中的OR毫无意义。创建操作应该如何决定创建新记录要满足的条件?这种关系是按定义只读的,因此它不是一种多关系

在这种情况下,一个简单的类方法或作用域将是正确的答案,而不是很多。要连接来自多个查询的结果,请使用

def internal_messages
  InternalMessage.where( id: sent_message_ids + received_message_ids)
end

要保持生成的对象可链接,即@user.internal\u messages.by\u date等。

好的,谢谢。反sql呢?不再需要了?在Rails 3中,由于DISTINCT的原因,我在不使用counter_SQL时经常会出现SQL错误。我自己从来没有这样做过,但我说可以在给定给has_many的块中定义自己的计数方法。因此,我想您可以在这里通过SQL执行def count proxy\u association.owner.class.count\u之类的操作;更新:Rails 4.2.5.1,ruby 2.3.1p112有很多:对话,->{proc{SOME SQL}}NoMethodError:undefined方法'Exception',当然,如果你想要结果的记忆,这是不好的,尤其是当它们使用重载时。有没有办法让rails在没有外键的情况下维护这些关系?