あなたが探しているものは、「nilガード」と呼ばれています。いくつかの便利なパターンはこのためにあります。
# safe navigation operator - if `nil_thing` is nil, `points` won't be called
nil_thing&.points
# the double ampersand check (what you've used)
if nil_thing && nil_thing.points == 100
# compound one-line conditional
do_stuff if nil_thing.points == 100 unless nil_thing.blank?
あなたはまた、多くの時間事態を回避することができ
:このクエリを組み立てている方法は、それが難しい回避することができることを
if student.scores.where(points: 100, assignment: team.assignment).exists?
do_stuff
end
注意N + 1個のクエリの問題。
私は、あなたと学生との間に適切な関係がないと思われます。私はStudentAssignment
にScore
の名前を変更し、それにscore
属性を持っているでしょう:
class Student
has_many :student_assignments
has_many :assignments, through: :student_assignments
end
class Assignment
has_many :student_assignments
has_many :students, through: :student_assignments
end
その後、あなたはRubyで、基本的な積極的なロードと価値の比較を使用することができます。
Assignment.includes(student_assignments: :students).each do |assignment|
puts "Scores for #{assignment.name}:"
assignment.student_assignments.each do |sa|
puts "#{sa.student.name} scored #{sa.score}"
puts "Congratulations to #{sa.student.name}" if sa.score >= 99
end
end
をあなたが他の方向からこれを行うことができますまた、学生をループさせて、スコアで課題を表示します。
生徒を課題多対多に接続する設定がない場合、perfect_scores
などの条件付きの関連付けを設定すると、ActiveRecordリレーションシップを利用して、それ以外の任意のクエリを熱心に読み込むことができます
class Student
has_many :scores
has_many :perfect_scores, -> { where(score: 100) }, class_name: 'Score', inverse_of: :student
def perfect_score_on_assignment?(assignment)
if perfect_scores.loaded?
# use cached data
perfect_scores.any? { |score| score.assignment_id == assignment.id }
else
# use sql to determine
perfect_scores.where(assignment: assignment).exists?
end
end
end
class Score
belongs_to: :student
belongs_to: :assignment
end
class Assignment
has_many :scores
end
# Load up all of the students and eager load perfect scores
@students = Student.includes(perfect_scores: :assignment)
@assignments = Assignment.all
@assignment.each do |assignment|
@students.each do |student|
if student.perfect_score_on_assignment?(assignment)
puts "#{student.name} scored 100%"
end
end
end
優れています。あなたの答えと一緒に役立つ説明をありがとう。私は、すべての学生とすべての課題をチェックする1つの関数を持っているので、これらの行は数千回実行されます。最高のパフォーマンスのためにどのパターンをお勧めしますか? –
@JeffZivkovicちょうどあなたの状況に応じてこれを処理する方法の2つの緩やかに仮説的な例で更新されました。 – coreyward
これ以上のことはありません。私はあなたの例を自分のアプリケーションに適応しようとします。 –