为什么 Mongoid::Criteria 可以使用对象的 as_json?

Why Mongoid::Criteria could use the object's as_json?

我是 RoR 的新手,在使用 Mongoid 时遇到问题。
代码是别人写的,我需要做一些修改
这是模型中的代码:

class AClass
  include Mongoid::Document  
  field :data, type: String  
  ...  
  scope ...  

  def self.search(params) 
    AClass.only(...)# return a Criteria Object
  end

  def as_json(options={})
    ...
  end

end

控制器中的代码:

def index
  @res = AClass.search(query_params) # @res is a Criteria Object
  respond_to do |format|
    format.json { render json: @res.as_json(format: params[:format], 
                                            path: request.env['ORIGINAL_FULLPATH']) } # why AClass's as_json is called
    format.xml  { render xml: @res.as_json(format: params[:format],
                                           path: request.env['ORIGINAL_FULLPATH']).
                                           to_xml(root: "root",
                                                  camelize: true) }
    format.html  
  end  
end

我有两个问题:

  1. 我发现 only 方法属于 Mongoid::CriteriaMongoid::Document 模块不包含 Criteria Class。上面的代码中只包含 Mongoid::Document。为什么 only 可以在 self.search 中调用?

  2. 发现Only的返回值为Mongoid::Criteria。但是,当我请求 json 数据时,@res.as_json 可以调用 AClassas_json 方法。为什么?

  1. I found only method belongs to Mongoid::Criteria and Mongoid::Document module does not contain the Criteria Class. Only Mongoid::Document is included in the code above. Why the only could be called in self.search?

only 方法可以在 Mongoid::Criteria::Queryable::Optional which is delegated to via Mongoid::Document 中找到(随意挖掘代码)。

  1. I found that the returned value of only is Mongoid::Criteria. However, when I request json data, the @res.as_json could call the AClass's as_json method. Why?

Mongoid::Criteria#as_json 在基础文档集合上调用 as_json,在每个基础文档上调用 as_json

mongoid/criteria.rb:

# Needed to properly get a criteria back as json
#
# @example Get the criteria as json.
#   Person.where(:title => "Sir").as_json
#
# @param [ Hash ] options Options to pass through to the serializer.
#
# @return [ String ] The JSON string.
def as_json(options = nil)
  entries.as_json(options)
end