Я пытаюсь найти лучший способ исправить проблему N + 1 в моем приложении rails.
Допустим, у меня есть модель Student
, которая имеет many
ассоциацию terms
.
student = Student.find_by_name('John')
student.terms
# [{term: 1}, {term: 2}, {term: 3}]
Итак, мне нужно иметь возможность отображать список студенческих терминов, но я также должен показывать предыдущий термин в том же виде. В настоящее время для этого у меня есть метод, который получает предыдущий термин по атрибуту start_at
, который является значением DateTime, эквивалентным первому дню срока.
# Term.rb
def previous_term
Term.where("start_at < ?", start_at).order(start_at: :desc).first&.start_at
end
Но использование этого метода в списке терминов делает запрос для каждого термина для каждого учащегося
- @terms.each do |term|
%td= term.start_at # list current term start_at
%td= term.previous_term # show previous term start_at - N+1 is here
Я думал о загрузке всех условий студента в контроллер и создании метода класса в модели Term, этот метод будет обнаруживать предыдущий термин из упорядоченного набора терминов.
# Term.rb
def self.get_previous(term_collection, term_id)
term_collection.detect do |term|
# logic to filter and get the previous term
end
end
Таким образом, это будет фильтрация объектов в памяти вместо создания соединений с базой данных, но я знаю, что есть лучший и более умный способ сделать это (возможно, лучшая практика?).