#ruby-on-rails #ruby #model #has-many
#ruby-on-rails #ruby #Модель #имеет много
Вопрос:
У меня есть переменная ( @cars
), содержащая данные из базы данных, и отсюда мне нужно сгенерировать документ XLS.
Из-за некоторых особенностей документа XLS мне нужно заранее знать длину некоторых ассоциаций (модель Car
имеет has_many
ассоциацию для модели PreviousOwner
) — в частности, мне нужно знать, сколько предыдущих владельцев было у каждого автомобиля, и мне нужно зафиксировать наибольшее количество предыдущих владельцев всех автомобилей.
Один из способов найти это — добавить counter_cache
к структуре Car
модели, есть ли какой-либо другой способ справиться с этой ситуацией? У меня есть @cars
переменная, и оттуда мне нужно найти автомобиль с большинством предыдущих владельцев.
Комментарии:
1. Если вам нужно количество связанных записей на регулярной основе, тогда
counter_cache
это правильный путь. Все остальные методы должны были бы пересчитывать число каждый раз, когда вы их читаете, что делает все остальные методы медленнее.
Ответ №1:
Один из способов справиться с этим — объединить и выбрать количество:
Car.left_joins(:previous_owners)
.select(
'cars.*',
'COUNT(previous_owners.*) AS previous_owners_count'
)
.group(:id)
.order(previous_owners_count: :desc)
Преимущества по сравнению с кешем счетчика:
- Никаких дополнительных запросов на обновление при вставке связанных записей.
- Более точный, если количество критично и у вас много операций записи.
Недостатки:
- Количество вычисляется для каждого запроса, который менее эффективен при чтении.
- Это мешает нетерпеливой загрузке записей.
- Большая сложность кода по сравнению с простым обратным вызовом модели.