ActiveRecord查询方法响应 - 需要神秘化

时间:2013-08-18 21:57:04

标签: ruby-on-rails ruby activerecord

简介:Rails 3.2; 'a'是一个对象,而ActiveRecord模型,有很多消息(也是ActiveRecord模型) - 虽然这对我的问题可能不是很重要。

所以这就是问题:为什么这样,

  • irb(main):046:0> a.messages.respond_to?(:where) => true

但也是这个,

  • irb(main):047:0> a.messages.methods.include?(:where) => false

发生了什么事?显然这里有一些Ruby魔法,这使得这些探索对象的方式产生不同的结果;一个是查询Array类,我猜,另一个是查询... thing 响应:where(以及其他方法)。甚至不知道该怎么称呼它。我的猜测是它用一些东西查询Array类的对象......'混入'? (想想我在Ruby上下文中使用的术语很多......)

1 个答案:

答案 0 :(得分:1)

这里的罪魁祸首可能是method_missing

很多"魔法" Ruby和Rails的各个方面都归功于这个漂亮的小方法。基本上,作为抛出NoMethodError之前的最后努力,Ruby在其对象上调用了一个名为method_missing的方法。这允许Rails(4.0之前版本)响应动态查找器,如find_by_name_and_email。在所有模型中定义所有可能的列组合是荒谬的,因此Rails重载method_missing并在那里构造相关的SQL查询。

此外,当您使用method_missing回复方法调用时,您可以覆盖Ruby的respond_to?方法。

以下是一个例子:

class Foo
  def method_missing(meth, *args, &block)
    if meth == :bar
      puts 'yep!'
    else
      super
    end
  end

  def respond_to?(meth)
    if meth == :bar
      true
    else
      super
    end
  end
end

foo = Foo.new
foo.methods.include?(:bar)
# => false
foo.respond_to?(:bar)
# => true