给出以下ActiveRecord模型:
class User < ActiveRecord::Base
has_many :games
def name
"Joe"
end
def city
"Chicago"
end
end
我想检索我直接添加到User类的方法列表(而不是通过扩展ActiveRecord和/或添加关联添加的方法)。示例输出:
["name","city"]
调用User.instance_methods(false)返回ActiveRecord添加的方法:
["validate_associated_records_for_games", "games", "game_ids", "games=", "game_ids=", "after_create_or_update_associated_records_for_games", "before_save_associated_records_for_games"]
以及数据库列中的任何模型属性。我想排除那些,只是在子类上获取自定义方法。
我的目的是方法跟踪:我想跟踪我的自定义方法,同时排除ActiveRecord添加的方法。
有什么想法吗?
答案 0 :(得分:1)
User.instance_methods - ActiveRecord::Base.instance_methods #=> [:name,:city]
更新:
这些方法的顺序很重要
class User < ActiveRecord::Base
def self.my_own_methods
self.instance_methods - @@im
end
has_many :games
@@im = self.instance_methods
def name
"Joe"
end
def city
"Chicago"
end
end
User.my_own_methods #=> [:name, :city]
这个测试过并且有效
答案 1 :(得分:0)
使用method_added
挂钩将方法名称添加到列表中,并使用猴子补丁Active Record,以便AR添加的方法不会添加到该列表中。
如果您不想破解AR并开始探索,您还可以定义一个“类宏”,它定义一个方法并将添加到列表中。对于您自己的自定义方法,请使用类宏而不是def
。
如果你不熟悉我所说的“类宏”,它只是一个这样的方法:
class Class
def mydef(name,&block)
(@methods || []) << name
define_method(name,&block)
end
end
使用像mydef
之类的东西来定义方法而不是def
绝对是丑陋的,但它可以在不需要任何猴子修补的情况下解决问题。