2017-08-07 10 views
0

最近、私は熱心な負荷とその性能を向上させる必要性に気づきました。このページの読み込みからいくつかのクエリを削除することができましたが、必要なレコードを正しく読み込めるようにすれば大幅に減らすことができます。私は熱心な負荷を実装するための助けが必要です

このコントローラは、ビューを埋めるために、次のすべてをロードする必要があります。

  • A学生が

  • のすべてを見ている学生

  • セミナー(クラス)ページそのセミナーに含まれる目的

  • 目的地セミナー、目的地間の結合表dセミナー。これには、教師によって設定され、目的の順序付けに使用される列「優先度」が含まれます。

  • 他の結合テーブルobjective_students。その目的に対する生徒の得点の列「ポイント」を含みます。

  • seminar_students、1つの最後の結合テーブル。学生が調整できるいくつかの設定が含まれています。

コントローラ:重複クエリの多くは思ったが、熱心なローディングによって除去されることになったことが発生している場合

def student_view 
    @student = Student.includes(:objective_students).find(params[:student]) 
    @seminar = Seminar.includes(:objective_seminars).find(params[:id]) 
    @oss = @seminar.objective_seminars.includes(:objective).order(:priority) 
    @objectives = @seminar.objectives.order(:name) 
    objective_ids = @objectives.map(&:id) 
    @student_scores = @student.objective_students.where(:objective_id => objective_ids) 
    @ss = @student.seminar_students.find_by(:seminar => @seminar) 
    @teacher = @seminar.user 

    @teach_options = teach_options(@student, @seminar, 5) 
    @learn_options = learn_options(@student, @seminar, 5) 
end 

以下の方法があります。この方法は生徒に6つの選択肢を与え、クラスメートを教える1つの目的を選ぶことができます。この方法では、まず、学生が75%から99%の間で得点した目標を調べます。そのブラケットの中には、 "優先度"(ソートされたobjective_seminarsの値)によってソートされています。この値は教師によって設定されます。優先順位によって。 (learn_options方法は、異なるブラケット番号と、この方法として実質的に同じである。)

teach_options方法:

def teach_options(student, seminar, list_limit) 
     teach_opt_array = [] 
     [[70,99],[100,100]].each do |n| 
      @oss.each do |os| 
       obj = os.objective 
       this_score = @student_scores.find_by(:objective => obj) 
       if this_score 
        this_points = this_score.points 
        teach_opt_array.push(obj) if (this_points >= n[0] && this_points <= n[1]) 
       end 
      end 
      break if teach_opt_array.length > list_limit 
     end 
     return teach_opt_array 
    end 

は、任意の洞察力のために事前にありがとうございます!

答えて

0

@jeff - あなたの質問に関しては、@student_scores.find_by(:objective => obj)の外で多くのクエリが発生する場所はわかりません。 あなたの@student_scoresオブジェクトは、すでにActiveRecordリレーションですか?したがって、.where()をこれに使用するか、または.select{}を再度使用しないでください。 SelectはAR Relationではなく配列を残しますので、そこには注意してください。

this_score = @student_scores.where(objectve: obj) 
this_score = @student_scores.select{|score| score.objective == obj} 

これらは動作するはずです。

あなたのトップコントローラの方法に関する他の提案 - ガードや防御コーディングが表示されないので、これらのオブジェクトのいずれかがゼロの場合、.order(:blah)はおそらくエラーになります。さらに、それらがnilを返すと、データに依存する後続のクエリでエラーが発生する可能性があります。私はいくつかのtry()または救助を選ぶだろう。

最後は、ちょうどnitpickyているが、それらの最初の2行は、その中に誤っ主な目的だけでなく、含まに適用されるものとしてのparamsを解釈することができ、少し読みにくい:

@student = Student.includes(:objective_students).find(params[:student]) 
@seminar = Seminar.includes(:objective_seminars).find(params[:id]) 

@student = Student.find(params[:student]).includes(:objective_students) 
@seminar = Seminar.find(params[:id]).includes(:objective_seminars) 
+0

を、あなたは「どこで」デシベルに別のヒットを送信しないと言ったが、「find_byは」いています:?私は、続く、あなたの主な目的で見つけるを入れたいですかもしそうなら、それは理にかなっています。また、チェーンの最後に「インクルード」を含む構文は、最初に試した方法でした。それはそのようなエラーを蹴った。 –

関連する問題