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

时间:2021-01-09 13:32:05

The code snippet has three methods: lambda, scope and class method.

代码片段有三种方法:lambda,scope和class方法。

All of them returns the same results.

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

Questions:

问题:

  1. Is there any best practice in Ruby/Rails when it is preferred to use one over the other ?
  2. Ruby / Rails中是否有最佳实践可供选择?
  3. In what cases would you use lambda, scope or class method ( best practices ).

    在什么情况下你会使用lambda,范围或类方法(最佳实践)。

    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 个解决方案

#1


4  

It's best to avoid using option 2. That code gets run immediately when your Rails app loads which is bad since it will always return the same value for any Time argument you use in it. That's because it isn't reevaluated every time it's called.

最好避免使用选项2.当您的Rails应用程序加载时,该代码会立即运行,因为它会始终为您在其中使用的任何Time参数返回相同的值。那是因为每次调用它都不会重新评估。

Option 1, as pointed out by musicnerd47, are lazy loaded and it is advisable that you pass lambdas to scopes in Rails 4 rather than doing option 2 since they are reevaluated every time called so they will return updated values.

选项1,由musicnerd47指出的那样,是懒惰的加载,这是可取的,你传递lambda表达式中的Rails 4作用域,而不是因为他们重新评估每一个调用,所以他们将返回更新的值时间做选择2。

So the only options would be 1 and 3. This is usually a matter of style that your team adheres to. In our company, we use option 1 when the code we pass to it is going to be an ActiveRecord query and we want it to output a query that can be chained. This is to ensure that an ActiveRecord::Relation object is returned every time we do our queries for multiple records. That would mean that they are always going to be chainable with other ActiveRecord::Relation methods and our other defined scopes.

所以唯一的选择是1和3.这通常是你的团队坚持的风格问题。在我们公司,我们使用选项1,当我们传递给它的代码将是一个ActiveRecord查询,我们希望它输出一个可以链接的查询。这是为了确保每次我们对多个记录进行查询时都返回一个ActiveRecord :: Relation对象。这意味着它们总是可以与其他ActiveRecord :: Relation方法和我们其他定义的范围链接。

We use option 3 if it's for behavior that doesn't need to be chained with other scopes.

我们使用选项3,如果它是针对不需要与其他范围链接的行为。

Here's a good read on the matter of scopes and class_methods where he goes into detail and provides examples on the difference between scopes and class methods. http://blog.plataformatec.com.br/2013/02/active-record-scopes-vs-class-methods/

这里有关于范围和class_methods的详细解读,他详细介绍了这些方法,并提供了范围和类方法之间差异的示例。 http://blog.plataformatec.com.br/2013/02/active-record-scopes-vs-class-methods/

#2


4  

Starting in Rails 4 you have to use a lambda - in general it is a better practice because it is lazily loaded and prevents a lot of traps, especially when dealing with dates and times.

从Rails 4开始,你必须使用lambda - 一般来说这是一个更好的练习,因为它是懒惰加载并防止大量陷阱,特别是在处理日期和时间时。

I think for simple scopes that deal with a single where call or something, using scope is okay. When it is more complex, then moving to a class method is better (for example, when you need to be calling other methods or setting local variables before you return the scope).

我认为对于处理单个调用或其他东西的简单范围,使用范围是可以的。当它更复杂时,移动到类方法会更好(例如,当您需要在返回范围之前调用其他方法或设置局部变量时)。

#3


0  

I would use the lambda. The function you're describing is sufficiently simple. Using the lambda initializes lazily as well. I direct you here to the rails style guide.

我会用lambda。您描述的功能非常简单。使用lambda也会懒惰地初始化。我指引你到这里的导轨风格指南。

#4


0  

Unfortunately there is no golden rule. Scopes are designed for this exact application. When the application of logic comfortably fits into a scope, I think that's the best bet. When things start to get too complex, it's usually best to move the logic into a class method.

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

#1


4  

It's best to avoid using option 2. That code gets run immediately when your Rails app loads which is bad since it will always return the same value for any Time argument you use in it. That's because it isn't reevaluated every time it's called.

最好避免使用选项2.当您的Rails应用程序加载时,该代码会立即运行,因为它会始终为您在其中使用的任何Time参数返回相同的值。那是因为每次调用它都不会重新评估。

Option 1, as pointed out by musicnerd47, are lazy loaded and it is advisable that you pass lambdas to scopes in Rails 4 rather than doing option 2 since they are reevaluated every time called so they will return updated values.

选项1,由musicnerd47指出的那样,是懒惰的加载,这是可取的,你传递lambda表达式中的Rails 4作用域,而不是因为他们重新评估每一个调用,所以他们将返回更新的值时间做选择2。

So the only options would be 1 and 3. This is usually a matter of style that your team adheres to. In our company, we use option 1 when the code we pass to it is going to be an ActiveRecord query and we want it to output a query that can be chained. This is to ensure that an ActiveRecord::Relation object is returned every time we do our queries for multiple records. That would mean that they are always going to be chainable with other ActiveRecord::Relation methods and our other defined scopes.

所以唯一的选择是1和3.这通常是你的团队坚持的风格问题。在我们公司,我们使用选项1,当我们传递给它的代码将是一个ActiveRecord查询,我们希望它输出一个可以链接的查询。这是为了确保每次我们对多个记录进行查询时都返回一个ActiveRecord :: Relation对象。这意味着它们总是可以与其他ActiveRecord :: Relation方法和我们其他定义的范围链接。

We use option 3 if it's for behavior that doesn't need to be chained with other scopes.

我们使用选项3,如果它是针对不需要与其他范围链接的行为。

Here's a good read on the matter of scopes and class_methods where he goes into detail and provides examples on the difference between scopes and class methods. http://blog.plataformatec.com.br/2013/02/active-record-scopes-vs-class-methods/

这里有关于范围和class_methods的详细解读,他详细介绍了这些方法,并提供了范围和类方法之间差异的示例。 http://blog.plataformatec.com.br/2013/02/active-record-scopes-vs-class-methods/

#2


4  

Starting in Rails 4 you have to use a lambda - in general it is a better practice because it is lazily loaded and prevents a lot of traps, especially when dealing with dates and times.

从Rails 4开始,你必须使用lambda - 一般来说这是一个更好的练习,因为它是懒惰加载并防止大量陷阱,特别是在处理日期和时间时。

I think for simple scopes that deal with a single where call or something, using scope is okay. When it is more complex, then moving to a class method is better (for example, when you need to be calling other methods or setting local variables before you return the scope).

我认为对于处理单个调用或其他东西的简单范围,使用范围是可以的。当它更复杂时,移动到类方法会更好(例如,当您需要在返回范围之前调用其他方法或设置局部变量时)。

#3


0  

I would use the lambda. The function you're describing is sufficiently simple. Using the lambda initializes lazily as well. I direct you here to the rails style guide.

我会用lambda。您描述的功能非常简单。使用lambda也会懒惰地初始化。我指引你到这里的导轨风格指南。

#4


0  

Unfortunately there is no golden rule. Scopes are designed for this exact application. When the application of logic comfortably fits into a scope, I think that's the best bet. When things start to get too complex, it's usually best to move the logic into a class method.

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