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
答案 0 :(得分:4)
从Rails 4开始,你必须使用lambda - 一般来说这是一个更好的做法,因为它是懒惰加载并防止了很多陷阱,特别是在处理日期和时间时。
我认为对于处理单个调用或其他内容的简单范围,使用scope
是可以的。如果它更复杂,那么移动到类方法会更好(例如,当您需要在返回范围之前调用其他方法或设置局部变量时)。
答案 1 :(得分:4)
最好避免使用选项2.当您的Rails应用加载时,该代码会立即运行,因为它会始终为您在其中使用的任何Time参数返回相同的值。那是因为每次调用它都不会重新评估。
如musicnerd47所指出的,选项1是延迟加载的,建议你将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 :(得分:0)
我会使用lambda。您描述的功能非常简单。使用lambda也会懒惰地初始化。我将here引导至rails样式指南。
答案 3 :(得分:0)
不幸的是,没有黄金法则。范围是为这个确切的应用而设计的。当逻辑的应用舒适地适合范围时,我认为这是最好的选择。当事情开始变得太复杂时,通常最好将逻辑移动到类方法中。