Rails:lambda,scope和class方法有什么区别?什么是最佳做法?

时间:2013-12-15 16:55:16

标签: ruby-on-rails ruby methods

code代码段有三种方法:lambdascopeclass method

所有这些都会返回相同的结果。

问题:

  1. Ruby/Rails优先使用一个而不是另一个时,是否有最佳做法?
  2. 在什么情况下,您会使用lambdascopeclass方法(最佳做法)。

    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
    

4 个答案:

答案 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)

不幸的是,没有黄金法则。范围是为这个确切的应用而设计的。当逻辑的应用舒适地适合范围时,我认为这是最好的选择。当事情开始变得太复杂时,通常最好将逻辑移动到类方法中。