我正在将序列化数据发送到一个需要访问Mongoid文档的类,该文档可能嵌入,也可能不嵌入。
对于嵌入的文档,我接受一个可变数量的参数来获取嵌入的文档。
代码很简单:

def perform(object, *arguments)
  @opts = arguments.extract_options!
  @object = arguments.reduce(object){|object, args| object.public_send(*args)}
  # [...]

我使用reduce是因为我只需要调用公共方法。
然而,当我试图访问一个嵌入的文档时,我得到了一些非常奇怪的结果,其中public_send是一个枚举器。
经过一些调试,我发现对于任何根文档@object和嵌入式集合object,我都有:
object.items.public_send(:find)
# => #<Enumerator: ...>
object.items.send(:find) # or __send__
# => nil

当我调用itemspublic_send时,调用的方法完全不同!
怎么可能呢?
正常吗?那是虫子吗?
send似乎调用了public_sendfind)的Array方法,但Enumerable(或send)调用了Mongoid的__send__方法。
编辑:简单可复制大小写:
require 'mongoid'

class User
  include Mongoid::Document

  field :name, type: String

  embeds_many :groups
end

class Group
  include Mongoid::Document

  field :name, type: String

  embedded_in :user
end

Mongoid.load_configuration({
  sessions: {
    default: {
      database: 'send_find',
      hosts: [
        'localhost:27017'
      ]
    }
  }
})

user = User.create(name: 'john')
user.groups.create(name: 'g1')
user.groups.create(name: 'g2')

puts "public_send :find"
puts user.groups.public_send(:find).inspect
# => #<Enumerator: [#<Group _id: 5530dea57735334b69010000, name: "g1">, #<Group _id: 5530dea57735334b69020000, name: "g2">]:find>
puts "send :find"
puts user.groups.send(:find).inspect
# => nil
puts "__send__ :find"
puts user.groups.__send__(:find).inspect
# => nil

最佳答案

好吧,经过几个小时的调试,我发现它实际上是Mongoid中的一个bug。
关系不是数组,而是数组周围的代理,它将大多数方法委托给数组。
由于public_send也被委派,但不是send__send__,所以行为不一样。
有关更多信息,请参阅mypull request和关联的提交。

关于ruby - Mongoid嵌入式集合对:find的响应,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29695736/

10-11 03:32
查看更多