2017-01-24 5 views
1

ユーザと問題との間の結合テーブルであるユーザ、問題、および試行があります。私は現在のユーザーの最新の試みと一緒に、すべての問題のインデックスを表示することを検討しています。Railsは条件付きで結合しました

条件付きの左結合を取得するために4つのことを試しましたが、どちらも機能しませんでした。

単純なアプローチ

@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) 

これは、すべての問題を取得する左結合(または同等の2つのクエリ)だけでなく、現在のユーザーのものだけでなく、すべての試みを行います。したがって...

@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) 

そして、これが 引数がサポートされていないインスタンスに参加すると言ってレールからのエラーメッセージを表示します。

だから私は立ち往生しています。これを行う最善の方法は何ですか? Arelは正しいツールですか?アクティブなレコードをスキップしてJSON BLOBを返すことはできますか?私はちょうど馬鹿になっていますか?

この質問は、this oneと非常によく似ていますが、サポートされていない結合スコープの引数が必要です。そして、私はここ数年でレールに何かを加えてほしいと思っています。

ありがとうございました。

答えて

0

私がこれを解決した方法は、raw SQLを使用することでした。それは醜いものであり、セキュリティ上のリスクですが、私は良くはありませんでした。

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

次に、メモリ内の結果配列を操作します。