【发布时间】:2020-02-09 17:35:05
【问题描述】:
我正在使用 find_by_sql 使用 Postgres 作为数据库服务器对我的 Conversationalist 模型进行查询:
Conversationalist.find_by_sql(['
SELECT * FROM (
SELECT * FROM conversationalists
WHERE conversable_id = ? AND conversable_type = ?
) t1
LEFT JOIN (
SELECT * FROM conversationalists
WHERE conversable_id = ? AND conversable_type = ?
) t2
ON t1.chat_id = t2.chat_id',
recipient_id, recipient_type, sender_id, sender_type])
如果有结果,它就可以正常工作。但是如果没有结果,那么我会得到一个带有空 Conversationalist 对象的数组:[#<Conversationalist id: nil, conversable_type: nil...>]
这是我在数据库上直接查询得到的结果:
我期待的是一个空数组,因为不应该返回任何行,而是得到一个结果。如果没有返回结果,我将如何获得一个空数组?
附加上下文
我想要做的基本上是聊天。当有人向另一个用户发送消息时,上面的代码首先检查这两个人是否已经在聊天。如果是,则将消息添加到聊天中。如果没有,则会创建一个新的聊天并添加消息:
class MessagesController < ApplicationController
def create
message = new_message
conversation = already_conversing?
if conversation.empty? || conversation.first.id.nil?
chat = Chat.new
chat.messages << message
chat.conversationalists << sender
chat.conversationalists << recipient
chat.save!
else
chat = Chat.find(conversation.first.chat_id)
chat.messages << message
end
head :ok
end
private
def new_message
Message.new(
sender_id: params[:sender_id],
sender_type: params[:sender_type],
recipient_id: params[:recipient_id],
recipient_type: params[:recipient_type],
message: params[:message]
)
end
def already_conversing?
Conversationalist.conversing?(
params[:recipient_id],
params[:recipient_type],
params[:sender_id],
params[:sender_type]
)
end
end
模型:
class Conversationalist < ApplicationRecord
def self.conversing?(recipient_id, recipient_type, sender_id, sender_type)
Conversationalist.find_by_sql(['
SELECT * FROM (
SELECT * FROM conversationalists
WHERE conversable_id = ? AND conversable_type = ?
) t1
LEFT JOIN (
SELECT * FROM conversationalists
WHERE conversable_id = ? AND conversable_type = ?
) t2
ON t1.chat_id = t2.chat_id',
recipient_id, recipient_type, sender_id, sender_type])
end
end
【问题讨论】:
-
我不明白你在这里的用法。您将整个想法封装在一个数组中。您可以尝试只调用
find_by_sql('Select... ')而不使用封闭数组或末尾的参数吗? -
我需要数组来绑定参数(recipient_id,recipient_type...)(api.rubyonrails.org/classes/ActiveRecord/Querying.html)。如果没有数组,你会得到一个错误:“参数数量错误(给定 5,预期 1..2)”
-
我明白你对参数的意思,我没有使用
find_by_sql我需要传递参数的地方,所以让我愣了一秒。感觉就像您的查询返回某种空行而不是 nil。这就是为什么我会在psql中运行它来看看你得到了什么。也很难可视化,因为我们不知道您的整个数据结构。你能发布一个完整的空对象inspect吗? -
很奇怪,我可以在我的一个项目上对其进行测试,并且 0 行总是给出一个空数组,就像您期望的那样。我认为这也是预期的行为,因为这是我一直得到的。您能否展示您最初发布的代码的一些上下文?它在 Rails 控制台上做同样的事情吗?
-
这有帮助。如果你只在 Rails 控制台上运行原始的
find_by_sql查询,它仍然返回一个空对象?
标签: ruby-on-rails postgresql activerecord