这是我的一段代码:
class Company < ActiveRecord::Base
has_many :employees
end
my_company = Company.first
employees = my_company.employees
puts employees.class
puts employees.methods.include? "create"
puts employees.respond_to? :create
运行上面代码后输出:
Array
false
true
即使我使用空方法体覆盖“employees.method_mising”,create方法仍然存在并成功运行。我想知道activerecord如何将“create”方法添加到“employees”对象中。使用Ruby调试器,我发现“create”方法可能会在类“ActiveRecord :: Associations :: AssociationCollection”中添加,我也试过阅读源代码,但这对我来说太复杂了,我找不到了原则下面。所以必须有人知道这个原则,对吗?你能教我一下吗?
答案 0 :(得分:0)
在阅读了active_record的源代码之后,我发现“employees”var是类“ActiveRecord :: Associations :: HasManyAssociation”的实例(&lt;“ActiveRecord :: Associations :: AssociationCollection”&lt;“ActiveRecord ::实际上是关联:: AssociationProxy“)。事实上,他们通过添加以下代码行来解决AssociationProxy中的几乎所有方法(包括“方法”,“类”等):
instance_methods.each { |m| undef_method m unless m.to_s =~ /^(?:nil\?|send|object_id|to_a)$|^__|^respond_to_missing|proxy_/ }
并且他们使用目标对象(在我的情况下,它是Array的一个实例)来委托“undef”ed方法,并且“respond_to?”等方法被委托给“proxy”对象,该对象具有“创建/构建“methods.So”employees.respond_to?:create“返回true,但调用”employees.methods“调用返回的方法列表不包含”create“方法。