Rails: Какая разница между лямбдой, областью и классом? Какая лучшая практика?
Фрагмент code
имеет три метода: lambda
, scope
и class method
.
Все они возвращают те же результаты.
Вопросы:
- Есть ли какая-либо передовая практика в
Ruby/Rails
, когда она предпочтительнее использовать одну над другой?
-
В каких случаях вы бы использовали метод lambda
, scope
или class
(лучшие практики).
class Cars < ActiveRecord::Base
attr_accessible :manufacturer, :price, :used
#one
scope :used_and_cheap_lambda, lambda { where('used = ?', true ).where('price >= ?',30000) }
#two
scope :used_and_cheap_scope, where('used = ?', true ).where('price >= ?',30000)
#three
def self.used_and_cheap_class
where('used = ?', true ).where('price >= ?',30000)
end
end
Cars.used_and_cheap_lambda.count
=> #24
Cars.used_and_cheap_class.count
=> #24
Cars.used_and_cheap_scope.count
=> #24
Ответы
Ответ 1
Лучше избегать использования опции 2. Этот код запускается немедленно, когда приложение Rails загружается, что плохо, так как оно всегда будет возвращать одно и то же значение для любого аргумента Time, который вы используете в нем. Это потому, что он не переоценивается каждый раз, когда он звонил.
Вариант 1, как указано в musicnerd47, лениво загружен, и желательно, чтобы вы передавали lambdas в области в Rails 4, а не выполняли опцию 2, поскольку они переоцениваются каждый раз, так что они возвращают обновленные значения.
Таким образом, единственными параметрами будут 1 и 3. Это обычно вопрос стиля, который придерживается ваша команда. В нашей компании мы используем параметр 1, когда код, который мы передаем ему, будет запросом ActiveRecord, и мы хотим, чтобы он выводил запрос, который может быть привязан. Это гарантирует, что объект ActiveRecord:: Relation возвращается каждый раз, когда мы выполняем наши запросы для нескольких записей. Это означало бы, что они всегда будут связаны с другими методами ActiveRecord:: Relation и нашими другими определенными областями.
Мы используем опцию 3, если она для поведения, которая не нуждается в цепях с другими областями.
Здесь хорошо читается вопрос о облаках и class_methods, где он подробно разбирается и дает примеры различий между областями и методами класса.
http://blog.plataformatec.com.br/2013/02/active-record-scopes-vs-class-methods/
Ответ 2
Начиная с Rails 4 вы должны использовать лямбда - в общем, это лучшая практика, потому что она лениво загружается и предотвращает много ловушек, особенно когда речь идет о датах и времени.
Я думаю, что для простых областей, имеющих дело с одним, где вызов или что-то, использование scope
в порядке. Когда он более сложный, лучше перейти к методу класса (например, когда вам нужно вызывать другие методы или устанавливать локальные переменные перед возвратом области).
Ответ 3
Я бы использовал лямбду. Функция, которую вы описываете, достаточно проста. Использование лямбда также инициализируется лениво. Я направляю вас здесь в руководство по стилю рельсов.
Ответ 4
К сожалению, нет золотого правила. Области предназначены для этого конкретного приложения. Когда приложение логики удобно вписывается в объем, я считаю, что это лучший выбор. Когда вещи начинают становиться слишком сложными, обычно лучше всего перевести логику в метод класса.