3

我想知道这个语法{:age.gt => 60},我从中找到了这个语法mongoid。它是如何工作的?我正在查看mongoid的源代码,它没有对Symbol类进行太多扩展,并且有一个matchers包含gt.rb,lt.rb,...的目录。这些文件用于条件逻辑:大于,小于比....我无法理解它与Symbol课堂的关系。

在普通的 irb 会话中,它显示一个错误:

NoMethodError: undefined method `gt' for :age:Symbol

任何人都可以解释我吗?

4

4 回答 4

3

这是由 mongoid 本身作为符号变形文件Mongoid::Criterion::Complex的一部分完成的。奇怪的是,这个文件不再存在于 master 分支中,但我在我的项目中使用 2.4.7 并且它存在于那里(它可能只是移动了,但我在 master 中找不到它)。

相当有趣的魔法。魔术我不会认为所有这些都是必要的,:field => { :$gt => 5 }对我来说看起来还不错,但无论如何:)

于 2012-05-26T17:38:21.773 回答
2

请参阅@rfunduk 对当前发布的 2.4.10 版本的回答。

在 master 分支中,它发生了变化。您现在可以在需要的origin库中找到它mongoid

https://github.com/mongoid/origin/blob/master/lib/origin/extensions/symbol.rb,特别是这个方法:

module Origin
  module Extensions
    module Symbol
      # ...
      module ClassMethods
        # Adds a method on symbol as a convenience for the MongoDB operator.
        #
        # @example Add the $in method.
        #   Symbol.add_key(:in, "$in")
        #
        # @param [ Symbol ] name The name of the method.
        # @param [ Symbol ] strategy The name of the merge strategy.
        # @param [ String ] operator The MongoDB operator.
        # @param [ String ] additional The additional MongoDB operator.
        #
        # @since 1.0.0
        def add_key(name, strategy, operator, additional = nil, &block)
          define_method(name) do
            method = "__#{strategy}__".to_sym
            Key.new(self, method, operator, additional, &block)
          end
        end

        # ...
      end
    end
  end
end

它根据主库中列出的匹配器添加 、 等gt方法(参见文件和文件夹)。gtemongoidstrategies.rbmatchers/

于 2012-05-26T17:39:02.253 回答
2

看起来相关代码在这里Mongoid::Extensions::Symbol::Inflections)。有时最容易在运行时使用以下方法深入研究这些内容Tracer

require 'tracer'
require 'mongoid'

Tracer.on {
  :test.gt
}

输出

#0:(irb):9:Object:-: -
#0:(eval):1:Mongoid::Extensions::Symbol::Inflections:>: -
#0:(eval):2:Mongoid::Extensions::Symbol::Inflections:-: -
#0:/home/abe/.rvm/gems/ruby-1.9.3-p125@deleteme/gems/mongoid-2.4.10/lib/mongoid/criterion/complex.rb:21:Mongoid::Criterion::Complex:>:       def initialize(opts = {})
#0:/home/abe/.rvm/gems/ruby-1.9.3-p125@deleteme/gems/mongoid-2.4.10/lib/mongoid/criterion/complex.rb:22:Mongoid::Criterion::Complex:-:         @key, @operator = opts[:key], opts[:operator]
#0:/home/abe/.rvm/gems/ruby-1.9.3-p125@deleteme/gems/mongoid-2.4.10/lib/mongoid/criterion/complex.rb:23:Mongoid::Criterion::Complex:<:       end
#0:(eval):3:Mongoid::Extensions::Symbol::Inflections:<: -
于 2012-05-26T17:41:44.203 回答
0

继续寻找...

...定义范围 DSL 的方法是

  • 猴子补丁Symbol或者Object直接使用方法
  • 添加method_missing并解析名称的含义
于 2012-05-26T17:18:17.883 回答