简介: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上下文中使用的术语很多......)
答案 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