简体   繁体   中英

Rails: What's the difference between lambda, scope and class method? What's best practice?

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

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. In what cases would you use lambda , scope or class method ( best practices ).

     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 

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.

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).

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.

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.

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.

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

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/

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM