Rails activerecord通过关系的has_many计数选择记录

时间:2017-03-21 16:14:15

标签: ruby-on-rails activerecord

每个角色都有多个对话(通过::聊天),每个对话都有多个角色(通过::聊天)。角色可能有一个对话只涉及一个其他角色(两个参与者),以及涉及相同角色和其他角色的其他对话(三个或更多参与者)。

我正在尝试构建一个只选择双参与者对话的查询。

以下内容给出了一个缺少的FROM子句条目错误。我尝试了许多排列并且无法做到正确。

字符

has_many :chats,  foreign_key: "character_id",
                  dependent: :destroy

has_many :conversations, through: :chats, source: :conversation

会话

has_many :chats,  foreign_key: "conversation_id",
                  dependent: :destroy

has_many :characters, through: :chats, source: :character

def self.FindOneToOneConversation(sender, recipient)
  @sender    = Character.find_by(callsign: sender)
  @recipient = Character.find_by(callsign: recipient)
  @senderConversations = @sender.conversations
  @senderAndRecipientConversation = @senderConversations.joins(:characters)
                                                        .where(characters: {id: @recipient.id})
                                                        .having("COUNT(character.id) < 3")

  return @senderAndRecipientConversation.first # .first because @senderAndRecipientConversations is a collection

end

日志:

PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "character"
LINE 1: ..._id" = $1 AND "characters"."id" = $2 HAVING COUNT(character....
                                                             ^

: SELECT  "conversations".* FROM "conversations" INNER JOIN "chats" "chats_conversations_join" ON "chats_conversations_join"."conversation_id" = "conversations"."id" INNER JOIN "characters" ON "characters"."id" = "chats_conversations_join"."character_id" INNER JOIN "chats" ON "conversations"."id" = "chats"."conversation_id" WHERE "chats"."character_id" = $1 AND "characters"."id" = $2 HAVING COUNT(character.id) < 3  ORDER BY "conversations"."id" ASC LIMIT 1
Completed 500 Internal Server Error in 24ms (ActiveRecord: 1.1ms)

ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "character"
LINE 1: ..._id" = $1 AND "characters"."id" = $2 HAVING COUNT(character....

我希望这会有效,但它会出现这个错误:

缺少表格“对话”的FROM子句条目

@senderAndRecipientConversation = Conversation.select('*, COUNT(chats.character_id)')
                                              .from("(#{@senderConversations.to_sql}) AS sender_conversations")
                                              .joins("
                                        INNER JOIN     chats
                                        ON             sender_conversations.id = chats.conversation_id
                                        GROUP BY       chats.conversation_id
                                        HAVING COUNT(chats.character_id) < 3
                                        ")

在回答第一个答案时,以下是有缺陷的,我无法理解为什么 - 它找到涉及收件人的所有对话,而不仅仅是一对一的对话:

@senderAndRecipientConversation = @senderConversations.joins(:characters)
                                                      .where(characters: {id: @recipient.id})
                                                      .group('conversations.id')
                                                      .having("COUNT(characters.id) < 3")

1 个答案:

答案 0 :(得分:0)

在使用GROUP子句之前,您需要HAVING条记录。尝试类似下面的内容

@senderConversations.joins(:characters)
  .where(characters: {id: @recipient.id})
  .group('character_id')
  .having("COUNT(character.id) < 3")