我有两个型号,
User
Membership
两人之间有以下关系
user has_many :memberships
我一直在试图找出构建方法所在的位置,以及如何在实例的方法列表中获取它。以下是显示我的delima
的调试器的输出(rdb:63) @user.memberships.respond_to?"build"
true
虽然以下是返回false,但它不会返回true ??
(rdb:63) @user.memberships.instance_methods.include?"build"
false
答案 0 :(得分:9)
有一点是instance_methods
接受一个可选的布尔参数,指示是否要查看实例祖先的方法。在你的情况下,我认为你想要instance_methods(true)
。
然而,似乎" build"根据{{3}},是一种自动生成的方法。通常,ActiveRecord中的自动生成方法是通过覆盖method_missing
并处理对"方法"的调用来实现的。实际上并不存在。还会覆盖responds_to
,以便类表明它会响应正确的调用。但是,因为那些"方法"没有实际定义,他们不会出现在instance_methods
列表中。
由于类respond_to
使用method_missing
的命令列表基本上是无限的,我很确定无法获取列表。例如,具有属性a,b,c和d的ActiveRecord模型将自动响应诸如find_by_a_and_b
和find_by_a_b_and_c
以及find_by_b_and_d
之类的调用等等。没有办法列出所有这些可能性。
答案 1 :(得分:5)
你可以尝试:
@user = User.first
@user.methods.grep /method_name/
但是,我认为你不会在列表中看到'build'或'create'。这些方法很可能是动态生成的
答案 2 :(得分:5)
请注意,instance_methods
会返回一个字符串或符号数组,具体取决于Ruby版本。
Ruby 1.8返回一个String数组,Ruby 1.9返回一个Symbol数组。
在Ruby 1.8中
"".respond_to?(:upcase)
# => true
"".class.instance_methods.include?("upcase")
# => false
"".class.instance_methods.include?(:upcase)
# => false
在Ruby 1.9中
"".respond_to?(:upcase)
# => true
"".class.instance_methods.include?("upcase")
# => false
"".class.instance_methods.include?(:upcase)
# => true
此外,必须在类上调用instance_methods
,而不是在实例上调用。