我有用户,问题和尝试,这是用户和问题之间的连接表。我希望显示所有问题的索引以及当前用户对每个问题的最新尝试(如果有的话)。
我已经尝试了四件事来获得有条件的左连接,但没有一件有效。
天真的方法就像......
@problems = Problem.enabled
@problems.each do { |prob|
prob.last_attempt = prob.attempts
.where(user_id: current_user.id)
.last
end
这会得到我想要的所有问题和尝试但是是N + 1个查询。所以......
@problems = Problem.enabled
.includes(:attempts)
这是左连接(或等效的两个查询)获得所有问题,但也是所有尝试,而不仅仅是当前用户的那些。所以......
@problems = Problem.enabled
.includes(:attempts)
.where(attempts: {user_id: current_user.id})
这只会获得当前用户已经尝试过的那些问题。 所以......
//problem.rb
has_many :user_attempts,
-> (user) { where(user_id: user.id) },
class_name: 'Attempt'
//problem_controller.index
@problems = Problem.enabled
.includes(:user_attempts, current_user)
这会给rails提供一条错误消息,说明与实例连接 参数不受支持。
所以我被卡住了。做这个的最好方式是什么? Arel是正确的工具吗?我可以跳过活动记录并返回JSON blob吗?我只是愚蠢吗?
这个问题与this one非常相似,但我需要一个不受支持的连接范围的参数。而且我希望在过去几年中铁路增加了一些东西。
非常感谢你的帮助。
答案 0 :(得分:0)
我解决这个问题的方法是使用原始sql。它很难看,也存在安全隐患,但我找不到更好的效果。
results = Problem.connection.exec_query(%(
SELECT *
FROM problems
LEFT JOIN (
SELECT *
//etc.
)
))
然后在内存中操作结果数组。