私は、コントローラーで作成した長蛇の列のロジックを使用するのではなく、スコープを使用してArelクエリをチェーンしようとしてきました。ただし、スコープは、すべてのレコードを取得して、ロジックを使用してそれらを選別するよりも低速です。では、なぜスコープが優れているのか疑問に思います。
これが私がしていることです:
- 質問には多くの答えがあります
- 答えは1つの質問に属します
- 質問には、並べ替えに使用する「question_type」列があります
まず、スコープの方法...
質問.rb:
scope :answered, joins(:answers).order('answers.created_at desc')
scope :dogs, where(:question_type => "dogs")
scope :cats, where(:question_type => "cats")
scope :mermaids, where(:question_type => "mermaids")
question_controller.rb:
@dogs_recently_answered = Question.answered.dogs.uniq[0..9]
@cats_recently_answered = Question.answered.cats.uniq[0..9]
@mermaids_recently_answered = Question.answered.mermaids.uniq[0..9]
次に、ビューで、これらのインスタンス変数(現在は最大10個の要素を含む配列)を循環し、結果を表示します。
ページの読み込みにかかる時間(5つの異なる時間)は次のとおりです。
535msで200OKを完了(ビュー:189.6ms | ActiveRecord:46.2ms)
573msで200OKを完了(ビュー:186.0ms | ActiveRecord:46.3ms)
577msで200OKを完了(ビュー:189.0ms | ActiveRecord:45.6ms)
532msで200OKを完了(ビュー:182.9ms | ActiveRecord:46.1ms)
577msで200OKを完了(ビュー:186.7ms | ActiveRecord:46.9ms)
さて、厄介なコントローラーの方法...
@answers = Answer.order("created_at desc")
@all_answered = []
@answers.each {|answer| @all_answered << answer.question}
@recently_answered = @all_answered.uniq
@dogs_all_answered = []
@cats_all_answered = []
@mermaids_all_answered = []
@recently_answered.each do |q|
if q.question_type == "dogs"
@dogs_all_answered << q
@dogs_recently_answered = @dogs_all_answered[0..9]
elsif q.question_type == "cats"
@cats_all_answered << q
@cats_recently_answered = @cats_all_answered[0..9]
elsif q.question_type == "mermaids"
@mermaids_all_answered << q
@mermaids_recently_answered = @mermaids_all_answered[0..9]
end
end
そして、これが今ページをロードするのにかかる時間です(5つの異なる時間):
475msで200OKを完了(ビュー:196.5ms | ActiveRecord:34.5ms)
480msで200OKを完了(ビュー:200.4ms | ActiveRecord:36.4ms)
434msで200OKを完了(ビュー:198.2ms | ActiveRecord:35.8ms)
475msで200OKを完了(ビュー:194.2ms | ActiveRecord:36.4ms)
475msで200OKを完了(ビュー:195.0ms | ActiveRecord:35.4ms)
それで...
読みやすさは別として、スコープでクエリを磨くことで何が得られるでしょうか?レコードが増えると、最終的には速くなりますか?