Rails离开了条件

时间:2017-01-24 17:23:48

标签: ruby-on-rails associations left-join

我有用户,问题和尝试,这是用户和问题之间的连接表。我希望显示所有问题的索引以及当前用户对每个问题的最新尝试(如果有的话)。

我已经尝试了四件事来获得有条件的左连接,但没有一件有效。

天真的方法就像......

@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非常相似,但我需要一个不受支持的连接范围的参数。而且我希望在过去几年中铁路增加了一些东西。

非常感谢你的帮助。

1 个答案:

答案 0 :(得分:0)

我解决这个问题的方法是使用原始sql。它很难看,也存在安全隐患,但我找不到更好的效果。

results = Problem.connection.exec_query(%(
    SELECT *
    FROM problems
    LEFT JOIN (
        SELECT * 
    //etc.
    )
))

然后在内存中操作结果数组。