Область видимости ActiveRecord Rails 3 и метод класса
-
29-10-2019 - |
Вопрос
Я новичок в новом интерфейсе запросов ActiveRecord, поэтому я все еще разбираюсь.
Я надеялся, что кто-нибудь сможет объяснить разницу между использованием кода scope
в модели ActiveRecord и простым использованием метода класса (например, self.some_method
)
Насколько я могу судить, область видимости всегда должна возвращать отношение, тогда как метод класса не обязательно должен это делать.Это правда?
Например, я подумал, что имеет смысл сделать что-то вроде:
общийНо это не работает.Я получаю эту ошибку:
общийОднако он работает как метод класса
общийМне интересно узнать, что думают люди о том, когда использовать области, а когда методы класса.Правильно ли я предполагаю, что область видимости всегда должна возвращать отношение, но метод класса может возвращать все, что захочет?
Решение
В Rails 2.x было больше различий, поскольку named_scopes не выполнял ваши запросы (так что вы могли их связывать), тогда как методы класса обычно выполняли запросы (так что вы не могли их связывать), если вы не вручнуюзаключил ваш запрос в вызов scoped(...)
.
В Rails 3 все возвращает код ActiveRecord::Relation
до тех пор, пока вам не потребуются фактические результаты, поэтому области могут быть связаны с методами класса и наоборот (пока методы класса возвращают объекты ActiveRecord::Relation
, а не какой-либо другой тип объекта (например, счетчик)).
Как правило, я использую записи сгенерированного кода кода для простых однострочных строк, чтобы отфильтровать свой набор результатов.Однако, если я делаю что-нибудь сложное в «области видимости», которое может потребовать подробной логики, лямбда-выражений, нескольких строк и т. Д., Я предпочитаю использовать метод класса.И как вы заметили, если мне нужно вернуть счетчики или что-то в этом роде, я использую метод класса.
Другие советы
Как упоминал Дилан в своем ответе, одно различие между областью действия и методом класса заключается в том, что области действия оцениваются, когдакласс загружен.Это может привести к неожиданному результату.
Например,
родовое словоподвержен ошибкам.Правильный способ - использовать лямбда
родовое словоЛямбда-блок вычисляется лениво.Итак, Date.today запускается, когда вы вызываете область видимости, а не когда класс оценивается.
Если вы используете метод класса, вам не нужно использовать лямбда.
родовое словоПоскольку с методом класса код запускается во время вызова метода.