为什么没有#is_a?使用 ActiveRecord::NamedScope::Scope 的实例

发布于 2024-12-11 04:23:35 字数 838 浏览 2 评论 0原文

我正在使用 Rails 2.3.9。为了说明这个问题,假设我们在模型上有一个命名范围:

class Book < ActiveRecord::Base
  named_scope :has_isbn, :conditions => 'isbn IS NOT NULL'
end

如果您获取命名范围的类,则返回 ActiveRecord::NamedScope::Scope

Book.has_isbn.class
# => ActiveRecord::NamedScope::Scope

但是,如果您使用 #is_a?=== 来确定它是否是一个范围,它返回 false

Book.has_isbn.is_a?(ActiveRecord::NamedScope::Scope)
# => false
ActiveRecord::NamedScope::Scope === Book.has_isbn
# => false

有谁知道为什么会发生这种情况?调用命名作用域会返回一个 ActiveRecord::NamedScope::Scope 的实例(如果你查看 Rails 代码中的 lib/active_record/named_scope.rb ,你可以看到它调用 Scope.new 并返回它),那么为什么 #is_a?=== 不返回 true

I'm using Rails 2.3.9. To illustrate the issue, suppose we have a named scope on a model:

class Book < ActiveRecord::Base
  named_scope :has_isbn, :conditions => 'isbn IS NOT NULL'
end

If you get the class of the named scope, ActiveRecord::NamedScope::Scope is returned:

Book.has_isbn.class
# => ActiveRecord::NamedScope::Scope

However, if you use #is_a? or === to figure out whether it is a scope, it returns false:

Book.has_isbn.is_a?(ActiveRecord::NamedScope::Scope)
# => false
ActiveRecord::NamedScope::Scope === Book.has_isbn
# => false

Does anyone know why this is happening? Calling a named scope returns an instance of ActiveRecord::NamedScope::Scope (if you look at lib/active_record/named_scope.rb in the Rails code, you can see it calls Scope.new and returns it), so why doesn't #is_a? and === return true?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

征﹌骨岁月お 2024-12-18 04:23:35

查看此代码 Scope 类:

NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? respond_to?).to_set
[].methods.each do |m|
  unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s)
    delegate m, :to => :proxy_found
  end
end

中的每个方法[].methods(即数组响应的每个方法)在 Scope 实例上定义以传递给 代理对象,除了中定义的方法NON_DELEGATE_METHODS 数组。这些未受影响,请注意其中列出了 class

因此,当您调用 scope.class 时,您会得到 Scope 作为响应。但是,当您调用 scope.is_a? 时,您实际上是在调用 scope.proxy_found.is_a?,并且本例中的代理对象是一个 Array代码>.

>> scope.is_a?(Array)
=> true

Check out this code from the Scope class:

NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? respond_to?).to_set
[].methods.each do |m|
  unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s)
    delegate m, :to => :proxy_found
  end
end

Every method in [].methods--that is, every method an array responds to--is defined on the Scope instance to pass through to the proxy object, except for the methods defined in the NON_DELEGATE_METHODS array. These are untouched, and notice that class is listed in there.

So, when you call scope.class, you get Scope as the response. But when you call scope.is_a?, you're actually calling scope.proxy_found.is_a?, and the proxy object in this case is an Array.

>> scope.is_a?(Array)
=> true
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文