ActiveRecord Rails 3 范围与类方法
我对 ActiveRecord 的新查询界面很陌生,所以我仍在弄清楚。
我希望有人能够解释在 ActiveRecord 模型中使用 scope
和仅使用类方法(即 self.some_method
)之间的区别
。总是期望返回一个关系,而类方法不一定必须返回。这是真的吗?
例如,我认为这样做是有意义的:
class Person
scope :grouped_counts, group(:name).count
end
但这不起作用。我收到此错误:
ArgumentError: Unknown key(s): communicating, failed, matched, unmatched
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activesupport-3.0.5/lib/active_support/core_ext/hash/keys.rb:43:in `assert_valid_keys'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activerecord-3.0.5/lib/active_record/relation/spawn_methods.rb:110:in `apply_finder_options'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activerecord-3.0.5/lib/active_record/named_scope.rb:110:in `block in scope'
from (irb):48
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands/console.rb:44:in `start'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands/console.rb:8:in `start'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
r
但是它确实可以作为类方法工作
def self.grouped_counts
group(:name).count
end
我有兴趣了解人们对何时使用范围以及何时使用类方法的想法。我是否正确地假设范围必须始终返回关系,但类方法可以返回它想要的任何内容?
I'm new to the new query interface of ActiveRecord so I'm still figuring things out.
I was hoping someone could explain the difference between using a scope
in an ActiveRecord model and just using a class method (ie self.some_method
)
From what I can gather, a scope is always expected to return a relation, whereas a class method doesn't necessarily have to. Is this true?
For instance, I thought it would make sense to do something like:
class Person
scope :grouped_counts, group(:name).count
end
But this doesn't work. I get this error:
ArgumentError: Unknown key(s): communicating, failed, matched, unmatched
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activesupport-3.0.5/lib/active_support/core_ext/hash/keys.rb:43:in `assert_valid_keys'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activerecord-3.0.5/lib/active_record/relation/spawn_methods.rb:110:in `apply_finder_options'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/activerecord-3.0.5/lib/active_record/named_scope.rb:110:in `block in scope'
from (irb):48
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands/console.rb:44:in `start'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands/console.rb:8:in `start'
from /Users/bradrobertson/.rvm/gems/ruby-1.9.2-p180@influitive/gems/railties-3.0.5/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
r
It does however work as a class method
def self.grouped_counts
group(:name).count
end
I'm interested to know peoples' thoughts on when to use scopes and when to use class methods. Am I correct in assuming that a scope must always return a relation, but a class method can return whatever it wants?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Rails 2.x 中存在更多差异,因为named_scopes 不执行查询(因此您可以链接它们),而类方法通常会执行查询(因此您无法链接它们),除非您手动包装查询在
scoped(...)
调用中。在 Rails 3 中,所有内容都会返回
ActiveRecord::Relation
直到您需要实际结果,因此作用域可以针对类方法进行链接,反之亦然(只要类方法返回ActiveRecord::关系对象,而不是其他对象类型(如计数))。
一般来说,我使用
scope
条目作为简单的单行语句来过滤结果集。但是,如果我在“范围”中做任何复杂的事情,可能需要详细的逻辑、lambda、多行等,我更喜欢使用类方法。正如您所发现的,如果我需要返回计数或类似的内容,我会使用类方法。There was more of a difference in Rails 2.x, since named_scopes did not execute your queries (so you could chain them), whereas class methods generally did execute the queries (so you could not chain them), unless you manually wrapped your query in a
scoped(...)
call.In Rails 3, everything returns an
ActiveRecord::Relation
until you need the actual results, so scopes can be chained against class methods and vice versa (as long as the class methods returnActiveRecord::Relation
objects, not some other object type (like a count)).Generally, I use
scope
entries for simple one-liners to filter down my result set. However, if I'm doing anything complicated in a "scope" which may require detailed logic, lambdas, multiple lines, etc., I prefer to use a class method. And as you caught, if I need to return counts or anything like that, I use a class method.正如 Dylan 在他的回答中提到的,作用域和类方法之间的一个区别是,作用域是在类被调用时评估的。已加载。这可能会导致意想不到的结果。
例如,
容易出错。正确的方法是使用 lambda
Lambda 块被延迟计算。因此 Date.today 在您调用作用域时运行,而不是
当评估班级时。
如果使用类方法,则不需要使用 lambda。
因为对于类方法,代码是在方法调用时运行的。
As Dylan alluded to in his answer, one difference between scope and class method is that scopes are evaluated when the class is loaded. This may lead to unexpected result.
For example,
is prone to error. The correct way is to use a lambda
Lambda block is lazily evaluated. So Date.today is run when you call the scope, not
when the class is evaluated.
If you use a class method, then you don't need to use lambda.
Because with class method, the code is run at the time of method call.