Ruby on Rails ActiveRecord 作用域与类方法 [英] Ruby on Rails ActiveRecord scopes vs class methods
问题描述
Rails 在内部将作用域转换为类方法,那么为什么我们不能使用类方法本身而不是使用作用域.
Rails internally converts scopes to class methods then why can't we use class methods itself instead of going with scopes.
推荐答案
14 个范围
[...]
为了定义一个简单的范围,我们在类中使用 scope
方法,传递我们希望在调用此范围时运行的查询:
14 Scopes
[...]
To define a simple scope, we use thescope
method inside the class, passing the query that we'd like to run when this scope is called:
class Article < ActiveRecord::Base
scope :published, -> { where(published: true) }
end
这和定义一个类方法完全一样,使用哪种方法看个人喜好:
This is exactly the same as defining a class method, and which you use is a matter of personal preference:
class Article < ActiveRecord::Base
def self.published
where(published: true)
end
end
特别注意:
这和定义一个类方法完全一样,使用哪个看个人喜好
This is exactly the same as defining a class method, and which you use is a matter of personal preference
还有一个再进一步(Rails3 指南也说了同样的话顺便说一句):
And a little further (the Rails3 guide says the same thing here BTW):
14.1 传入参数
[...]
使用类方法是接受作用域参数的首选方式.
14.1 Passing in arguments
[...]
Using a class method is the preferred way to accept arguments for scopes.
所以你使用哪个是一个偏好问题,甚至建议你对带参数的作用域使用类方法.
So which you use is a matter of preference and it is even recommended that you use class methods for scopes that take arguments.
使用 scope
主要是一个符号问题.如果你说 scope :whatever
那么你明确地说 whatever
是一个查询构建器;如果你说 def self.whatever
那么你并没有暗示 whatever
方法的意图,你只是定义了一些可能会或可能不会表现的类方法就像一个范围.
Using scope
is mostly a notational issue. If you say scope :whatever
then you're explicitly saying that whatever
is meant to be a query builder; if you say def self.whatever
then you're not implying anything about the intent of the whatever
method, you're just defining some class method that may or may not behave like a scope.
当然,14.1 建议您在范围接受参数时不要使用 scope
,从而使这种符号区别变得一团糟.还要记住,在 Rails3 中,您可以说:
Of course, 14.1 makes a mess of this notational distinction by recommending that you not use scope
when your scope takes arguments. Also keep in mind that in Rails3 you could say:
scope :published, where(published: true)
所以一个无参数的作用域在视觉上是干净的"和简洁的,但是添加一个 lambda 来处理参数会使它看起来更混乱:
so an argumentless scope was visually "clean" and terse but adding a lambda to handle arguments would make it look messier:
scope :pancakes, ->(x) { where(things: x) }
但是 Rails4 即使对于无参数的作用域也需要 lambda,现在这种区分更没有意义了.
But Rails4 wants lambdas even for argumentless scopes the distinction makes even less sense now.
我怀疑此时的差异是历史性的.Scopes 在以前可能是一些特别的东西,但在 Rails3 时代变成了普通的旧类方法,以减少重复并更好地与 Rails3 附带的新查询界面相结合.
I suspect that the difference is historical at this point. Scopes were probably something special back in the before times but became plain old class methods in the Rails3 era to cut down on duplication and to better mesh with the new query interface that came with Rails3.
因此,如果您愿意,您可以跳过 scope
并直接转到类方法.当您的范围需要参数时,您甚至被鼓励这样做.
So you can skip scope
and go straight to class methods if you wish. You're even encouraged to do so when your scope takes arguments.
这篇关于Ruby on Rails ActiveRecord 作用域与类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!