Прежде чем рассматривать какие-либо проблемы с производительностью, вы должны знать, что написанный вами код вызовет ошибки, найдя Книги, которые не должны быть найдены.
Например, если @school.id
= 10 и @class.id
= 15, этот запрос вернет книгу с полями, в которых можно забронировать: bookable_id
= 15 и bookable_type
= "Школа".
Эта книга принадлежит другой школе!
Это может быть проще сделать:
@books = Book.where(bookable: @school).to_a.concat(Book.where(bookable: @class).to_a)
Это полиморфный синтаксический сахар для:
@books = Book.where(bookable_type: @school.class.to_s, bookable_id: @school.id).to_a.concat(Book.where(bookable_type: @class.class.to_s, bookable_id: @class.id).to_a)
Другими словами, просто сделайте два поиска и объедините результаты.
Что касается производительности, использование синтаксиса, такого как where(my_attribute: [value1, value2, value3])
, приведет к SQL, подобному WHERE books.my_attribute IN (value1, value2, value3)
.
Операторы SQL, использующие IN, могут быть неэффективными, поскольку они затрудняют использование сервером базы данных индексов в поле my_attribute
(в данном случае bookable_id
).
Наконец, вам следует рассмотреть возможность переименования модели Class
в Course
, чтобы избежать коллизий пространства имен с ключевым словом Ruby class
или путаницы программиста при чтении имен переменных.Рассмотрим неловкость bookable_type: @class.class.to_s